/** ****************************************************************************** * @file : app_tof.c * @author : IMG SW Application Team * @brief : This file provides code for the configuration * of the STMicroelectronics.X-CUBE-TOF1.3.2.0 instances. ****************************************************************************** * * @attention * * Copyright (c) 2022 STMicroelectronics. * All rights reserved. * * This software is licensed under terms that can be found in the LICENSE file * in the root directory of this software component. * If no LICENSE file comes with this software, it is provided AS-IS. * ****************************************************************************** */ #ifdef __cplusplus extern "C" { #endif /* Includes ------------------------------------------------------------------*/ #include "app_tof.h" #include "main.h" #include "sys_app.h" #include #include "usart.h" #if (defined(STS_P2)||defined(STS_T6)) #include "VL53L1X_api.h" #elif defined(L8) #include "53l8a1_ranging_sensor.h" #include "app_tof_pin_conf.h" #endif #include "stm32wlxx_nucleo.h" int example11(void); /* Private typedef -----------------------------------------------------------*/ /* * The application is to showcase the threshold detection * functionality of this device. * * When the device detects a target that match the configuration an IT is generated * and the host will start printing the measurement information on the serial connection (UART). * * Here is the default configuration: * * ITConfig.Criteria = RS_IT_IN_WINDOW; * ITConfig.LowThreshold = 200; // distance in mm * ITConfig.HighThreshold = 600; // distance in mm * * Other availables interrupt generation criteria for this device are: * * - RS_IT_DEFAULT // IT if new measurement is ready (no thresholds) * - RS_IT_IN_WINDOW // IT if distance > thresh_high * - RS_IT_OUT_OF_WINDOW // IT if distance < LowThreshold OR distance > HighThreshold * - RS_IT_BELOW_LOW // IT if distance <= LowThreshold * - RS_IT_ABOVE_HIGH // IT if distance > HighThreshold * - RS_IT_EQUAL_LOW // IT if distance == LowThreshold * - RS_IT_NOT_EQUAL_LOW // IT if distance != LowThreshold */ /* Private define ------------------------------------------------------------*/ #define TIMING_BUDGET (30U) /* 16 ms < TimingBudget < 500 ms */ #define POLLING_PERIOD (250U) /* refresh rate for polling mode (milliseconds, shall be consistent with TimingBudget value) */ #ifdef L8 /* for VL53L8A1 */ #define RANGING_FREQUENCY (10U) /* Ranging frequency Hz (shall be consistent with TimingBudget value) */ #define LOW_THRESHOLD (2000U) #define HIGH_THRESHOLD (2600U) /* Private variables ---------------------------------------------------------*/ static RANGING_SENSOR_Capabilities_t Cap; static RANGING_SENSOR_ProfileConfig_t Profile; static RANGING_SENSOR_Result_t Result; //static VL53L8CX_ResultsData L8CXResult; //static VL53L8CX_Motion_Configuration motion_config; /* Motion configuration*/ static void MX_53L8A1_ThresholdDetection_Init(void); static void MX_53L8A1_ThresholdDetection_Process(void); static void print_result(RANGING_SENSOR_Result_t *Result); #endif static int32_t status = 0; volatile uint8_t ToF_EventDetected = 0; uint16_t sensor_id=0; /* Private function prototypes -----------------------------------------------*/ #if (defined(STS_P2)||defined(STS_T6)) uint8_t sts_vl53lx_ranging(uint16_t *ranged_distance, uint8_t range_mode, uint16_t distance_threshold_mm, uint16_t inter_measurement_ms, uint16_t macro_timing,uint16_t roi_width, uint16_t sigma_mm, uint16_t signal_kcps); #endif uint8_t IsInterruptDetected(uint16_t dev); #if (defined(STS_P2)||defined(STS_T6)) void STS_TOF_VL53LX_Range_Process(uint8_t range_mode, uint16_t *range_distance); #endif void MX_TOF_Init(void) { /* USER CODE BEGIN SV */ /* USER CODE END SV */ /* USER CODE BEGIN TOF_Init_PreTreatment */ /* USER CODE END TOF_Init_PreTreatment */ /* Initialize the peripherals and the TOF components */ APP_LOG(TS_OFF,VLEVEL_L,"\r\n###################### MX TOF Init... \r\n"); //MX_53L1A2_SimpleRanging_Init(); //STS_TOF_VL53LX_PeopleCounting_Process(); #ifdef L8 //MX_53L8A1_ThresholdDetection_Init(); //MX_53L8A1_ThresholdDetection_Process(); example11_init(); #endif /* USER CODE BEGIN TOF_Init_PostTreatment */ /* USER CODE END TOF_Init_PostTreatment */ } /* * LM background task */ uint16_t MX_TOF_Ranging_Process(void) { #if (defined(STS_P2)||defined(STS_T6)) uint16_t range_distance=0; uint8_t range_mode = 2; //STS_TOF_LONG_RANGE; STS_TOF_VL53LX_Range_Process(range_mode, &range_distance); APP_LOG(TS_OFF, VLEVEL_M, "\n VL53L1 Range distance =%u mm \n\r", (uint16_t)range_distance); return (uint16_t) range_distance; #elif defined(L8) uint16_t range_distance=0; uint8_t center_roi[4] = {27,28,35,36}; uint8_t range_mode = 2; //STS_TOF_LONG_RANGE; int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result); printf("\r| 27 | 28 | 35 | 36 |\r\n"); for (uint8_t zone_nbr = 0; zone_nbr < 4; zone_nbr++) { /* Print distance and status */ if (Result.ZoneResult[center_roi[zone_nbr]].NumberOfTargets > 0) { printf("| %04ld %2ld", (long)Result.ZoneResult[center_roi[zone_nbr]].Distance[RANGING_SENSOR_NB_TARGET_PER_ZONE-1], (long)Result.ZoneResult[center_roi[zone_nbr]].Status[RANGING_SENSOR_NB_TARGET_PER_ZONE-1]); } else { printf("| -- "); } range_distance += Result.ZoneResult[center_roi[zone_nbr]].Distance[RANGING_SENSOR_NB_TARGET_PER_ZONE-1]; } //printf("\n\r"); range_distance /=4; printf("| %u mm\r\n", (uint16_t)range_distance); return (uint16_t) range_distance; #endif } void MX_TOF_Process(void) { /* USER CODE BEGIN TOF_Process_PreTreatment */ /* USER CODE END TOF_Process_PreTreatment */ //APP_LOG(TS_OFF,VLEVEL_L,"\r\n# MX TOF Process... #\r\n"); //STS_TOF_VL53LX_Range_Process(); //STS_TOF_VL53LX_PeopleCounting_Process(); //sts_tof_vl53lx_peoplecount_subprocess(); #ifdef L8 //MX_53L8A1_ThresholdDetection_Process(); //STS_TOF_L8_Process(); example11_process(); #endif /* USER CODE BEGIN TOF_Process_PostTreatment */ /* USER CODE END TOF_Process_PostTreatment */ } #ifdef L8 void STS_TOF_L8_Process(void) { //while (1) { /* interrupt mode */ if (ToF_EventDetected != 0) { ToF_EventDetected = 0; status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result); if (status == BSP_ERROR_NONE) { print_result(&Result); } } } } void STS_Reset_Sensor(void) { /* Sensor reset */ HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_RESET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_SET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_RESET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_SET); HAL_Delay(2); } /* VL53L8A1 */ static void MX_53L8A1_ThresholdDetection_Init(void) { /* Initialize Virtual COM Port */ //BSP_COM_Init(COM1); MX_USART2_UART_Init(); /* Sensor reset */ HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_RESET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_PWR_EN_C_PORT, VL53L8A1_PWR_EN_C_PIN, GPIO_PIN_SET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_RESET); HAL_Delay(2); HAL_GPIO_WritePin(VL53L8A1_LPn_C_PORT, VL53L8A1_LPn_C_PIN, GPIO_PIN_SET); HAL_Delay(2); status = VL53L8A1_RANGING_SENSOR_Init(VL53L8A1_DEV_CENTER); if (status != BSP_ERROR_NONE) { printf("VL53L8A1_RANGING_SENSOR_Init failed\n"); //while (1); } } static void MX_53L8A1_ThresholdDetection_Process(void) { uint32_t Id; RANGING_SENSOR_ITConfig_t ITConfig; VL53L8A1_RANGING_SENSOR_ReadID(VL53L8A1_DEV_CENTER, &Id); VL53L8A1_RANGING_SENSOR_GetCapabilities(VL53L8A1_DEV_CENTER, &Cap); Profile.RangingProfile = RS_PROFILE_8x8_AUTONOMOUS; Profile.TimingBudget = TIMING_BUDGET; Profile.Frequency = RANGING_FREQUENCY; /* Ranging frequency Hz (shall be consistent with TimingBudget value) */ Profile.EnableAmbient = 0; /* Enable: 1, Disable: 0 */ Profile.EnableSignal = 0; /* Enable: 1, Disable: 0 */ /* set the profile if different from default one */ VL53L8A1_RANGING_SENSOR_ConfigProfile(VL53L8A1_DEV_CENTER, &Profile); /* threshold parameters */ ITConfig.Criteria = RS_IT_IN_WINDOW; ITConfig.LowThreshold = LOW_THRESHOLD; /* mm */ ITConfig.HighThreshold = HIGH_THRESHOLD; /* mm */ VL53L8A1_RANGING_SENSOR_ConfigIT(VL53L8A1_DEV_CENTER, &ITConfig); // L8CX Motion #if 0 /*********************************/ /* Program motion indicator */ /*********************************/ /* Create motion indicator with resolution 8x8 */ int status = vl53l8cx_motion_indicator_init(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); if(status) { printf("Motion indicator init failed with status : %u\n", status); return status; } /* (Optional) Change the min and max distance used to detect motions. The * difference between min and max must never be >1500mm, and minimum never be <400mm, * otherwise the function below returns error 127 */ status = vl53l8cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 1000, 2000); if(status) { printf("Motion indicator set distance motion failed with status : %u\n", status); return status; } /* If user want to change the resolution, he also needs to update the motion indicator resolution */ status = vl53l8cx_set_resolution(&Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_motion_indicator_set_resolution(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); // L8 Motion #endif status = VL53L8A1_RANGING_SENSOR_Start(VL53L8A1_DEV_CENTER, RS_MODE_ASYNC_CONTINUOUS); if (status != BSP_ERROR_NONE) { printf("VL53L8A1_RANGING_SENSOR_Start failed\n"); while (1); } printf("\033[2H\033[2J"); printf("53L8A1 Threshold Detection demo application\n\r"); printf("-------------------------------------------\n\r"); printf("please put a target between %d and %d millimeters from the sensor\n\r", LOW_THRESHOLD, HIGH_THRESHOLD); #if 1 //while (1) { /* interrupt mode */ if (ToF_EventDetected != 0) { ToF_EventDetected = 0; status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result); if (status == BSP_ERROR_NONE) { print_result(&Result); } } } #endif } static void print_result(RANGING_SENSOR_Result_t *Result) { int8_t i; int8_t j; int8_t k; int8_t l; uint8_t zones_per_line; zones_per_line = ((Profile.RangingProfile == RS_PROFILE_8x8_AUTONOMOUS) || (Profile.RangingProfile == RS_PROFILE_8x8_CONTINUOUS)) ? 8 : 4; printf("%c[2H", 27); /* clear screen */ printf("53L8A1 Threshold Detection demo application\n\r"); printf("-------------------------------------------"); printf("-------- Low= %4d High= %4d ------------", LOW_THRESHOLD, HIGH_THRESHOLD); printf("Cell Format :"); for (l = 0; l < RANGING_SENSOR_NB_TARGET_PER_ZONE; l++) { printf(" \033[38;5;10m%20s\033[0m : %20s\n", "Distance [mm]", "Status\r"); if ((Profile.EnableAmbient != 0) || (Profile.EnableSignal != 0)) { printf(" %20s : %20s\n", "Signal [kcps/spad]", "Ambient [kcps/spad]\r"); } } printf("\n\n"); for (j = 0; j < Result->NumberOfZones; j += zones_per_line) { for (i = 0; i < zones_per_line; i++) /* number of zones per line */ { printf(" -----------------"); } printf("\n"); for (i = 0; i < zones_per_line; i++) { printf("| "); } printf("|\n"); for (l = 0; l < RANGING_SENSOR_NB_TARGET_PER_ZONE; l++) { /* Print distance and status */ for (k = (zones_per_line - 1); k >= 0; k--) { if (Result->ZoneResult[j + k].NumberOfTargets > 0) { /* ---- origin printf("| \033[38;5;10m%5ld\033[0m :%2d%5ld ", (long)Result->ZoneResult[j + k].Distance[l],(j+k), (long)Result->ZoneResult[j + k].Status[l]); */ int32_t roi_distance =(uint32_t)(Result->ZoneResult[j + k].Distance[l]); int16_t roi_low = (roi_distance - LOW_THRESHOLD)/10; int16_t roi_high = (HIGH_THRESHOLD - roi_distance)/10; if ((roi_low> 0)&&(roi_high>0)) { //printf("| \033[38;5;10m%5ld\033[0m :%2d%5ld ", (uint32_t)(roi_distance-LOW_THRESHOLD), (j+k), (uint32_t)Result->ZoneResult[j + k].Status[l]); printf("| \033[38;5;10m%5d\033[0m : ", (uint16_t)roi_low); } else if ((roi_low< 0)|| (roi_high<0)) { //printf("| \033[38;5;10m%5s\033[0m :%2d%5ld ", ".",(j+k), (uint32_t)Result->ZoneResult[j + k].Status[l]); printf("| \033[38;5;10m%5s\033[0m : ", "."); } } else printf("| %5s : %5s ", ".", "."); } printf("|\n"); if ((Profile.EnableAmbient != 0) || (Profile.EnableSignal != 0)) { /* Print Signal and Ambient */ for (k = (zones_per_line - 1); k >= 0; k--) { if (Result->ZoneResult[j + k].NumberOfTargets > 0) { if (Profile.EnableSignal != 0) { printf("| %5ld : ", (long)Result->ZoneResult[j + k].Signal[l]); } else printf("| %5s : ", "X"); if (Profile.EnableAmbient != 0) { printf("%5ld ", (long)Result->ZoneResult[j + k].Ambient[l]); } else printf("%5s ", "X"); } else printf("| %5s : %5s ", "X", "X"); } printf("|\n"); } } } for (i = 0; i < zones_per_line; i++) { printf(" -----------------"); } printf("\n"); } #endif #if defined(STS_P2)||defined(STS_T6) uint8_t IsInterruptDetected(uint16_t dev) { // To be filled with customer HW. This function should // return 1 when an interrupt is raised by the ToF on GPIO1 pin (pin7) if (ToF_EventDetected ) { APP_LOG(TS_OFF, VLEVEL_L,"############### TOF EVENT DETECTED \r\n"); ToF_EventDetected =0; return 1; } else { return 0; } } #endif #if (defined(STS_P2)||defined(STS_T6)) void STS_TOF_VL53LX_Range_Process(uint8_t range_mode, uint16_t *range_distance) { //uint8_t vl53lx_model = STS_TOF_VL53L1X; //uint8_t range_mode = STS_TOF_SHORT_RANGE; uint16_t i_distance_measured = 0; uint16_t i_distance_threshold_mm = 800; uint16_t i_inter_measurement_ms=100, i_macro_timing=33; uint16_t i_roi_width=16, i_sigma_mm=30, i_signal_kcps=2000; switch (range_mode) { case STS_TOF_SHORT_RANGE: // STS ---002 for short distance /* Example for robust and short distance measurements. Max distance reduced * but very low number of false-positives */ //status |= VL53L1X_ULP_SetSigmaThreshold(dev, 30); //status |= VL53L1X_ULP_SetSignalThreshold(dev, 2000); i_sigma_mm = 30; //increase this for longer distance, reduce for shorter distance i_signal_kcps = 2000; // 1000- 6000 kcps i_distance_threshold_mm = 900; i_inter_measurement_ms = 100; // 100 - 1000 ms i_macro_timing = 100; //i_roi_width = 16; break; case STS_TOF_LONG_RANGE: // STS --- 003 for long range /* Relax some limits. Be careful, it can create false-positives !*/ //status |= VL53L1X_ULP_SetSigmaThreshold(dev, 60); //status |= VL53L1X_ULP_SetSignalThreshold(dev, 1200); i_sigma_mm = 85; // increase this for longer distance, reduce for short distance i_signal_kcps = 1000; // 1000- 6000 kcps i_distance_threshold_mm = 4000; //4000; i_inter_measurement_ms = 200; // 100 - 1000 ms i_macro_timing = 30; // 1 - 100 ms i_roi_width = 8; break; case STS_TOF_LOW_POWER_RANGE: // STS---001 for ultra low power /* Reduce the macro timing to minimum. This is equivalent as reducing the integration time */ //status = VL53L1X_ULP_SetMacroTiming(dev, 1); i_distance_threshold_mm = 4000; i_inter_measurement_ms = 100; // 100 - 1000 ms i_macro_timing = 1; /* Reduce at maximum the SPADS */ //status = VL53L1X_ULP_SetROI(dev, 4); i_roi_width = 4; break; default: break; } sts_vl53lx_ranging(&i_distance_measured, range_mode, i_distance_threshold_mm, i_inter_measurement_ms,i_macro_timing, i_roi_width, i_sigma_mm, i_signal_kcps); APP_LOG(TS_OFF, VLEVEL_M, "I_DISTANCE_MEASURED = %d \n", i_distance_measured); *range_distance = i_distance_measured; } void BSP_PB_Callback(Button_TypeDef Button) { //PushButtonDetected = 1; } uint8_t sts_vl53lx_ranging(uint16_t *ranged_distance, uint8_t range_mode, uint16_t distance_threshold_mm, uint16_t inter_measurement_ms, uint16_t macro_timing, uint16_t roi_width, uint16_t sigma_mm, uint16_t signal_kcps) { uint8_t status=0, dev=0x52; uint16_t estimated_distance_mm=0; status = VL53L1X_SensorInit(dev); status += VL53L1X_SetDistanceMode(dev, 2); /* 1=short, 2=long, DISTANCE_MODE */ status += VL53L1X_SetTimingBudgetInMs(dev, 100); /* TIMING_BUDGET, in ms possible values [15, 20, 50, 100, 200, 500] */ status += VL53L1X_SetInterMeasurementInMs(dev, 50); status += VL53L1X_SetROI(dev, 8, 8); /* minimum ROI 4,4 */ if (status != 0) { APP_LOG(TS_OFF, VLEVEL_L,"Initialization or configuration of the device\n"); return (-1); } status = VL53L1X_StartRanging(dev); /* This function has to be called to enable the ranging */ if (status != 0) { APP_LOG(TS_OFF, VLEVEL_L,"Start Range failed\n"); return (-1); } status = VL53L1X_GetDistance(dev, &estimated_distance_mm); APP_LOG(TS_OFF,VLEVEL_M,"Target detected! Distance =%d mm \r\n", estimated_distance_mm ); *ranged_distance = estimated_distance_mm; status = VL53L1X_StopRanging(dev); APP_LOG(TS_OFF,VLEVEL_M,"End of VL53L1X Ranging Process\n"); return status; #if 0 /*********************************/ /* VL53L1X ranging variables */ /*********************************/ uint8_t status, loop; uint8_t dev; //uint16_t sensor_id=0; uint8_t measurement_status; uint16_t estimated_distance_mm, r_signal_kcps, r_sigma_mm, r_ambient_kcps; /*********************************/ /* Customer platform */ /*********************************/ /* Default VL53L1X Ultra Low Power I2C address */ dev = 0x52; /* (Optional) Change I2C address */ // status = VL53L1X_ULP_SetI2CAddress(dev, 0x52); // dev = 0x20; /*********************************/ /* Power on sensor and init */ /*********************************/ APP_LOG(TS_OFF,VLEVEL_L,"Range Mode =%d \r\n",range_mode); /* (Optional) Check if there is a VL53L1X sensor connected */ status = VL53L1X_GetSensorId(dev, &sensor_id); APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X address =%X\r\n",sensor_id ); if(status || (sensor_id != 0xEACC)) { APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X not detected at requested address\n"); return status; } /* (Mandatory) Init VL53L1X sensor */ status = VL53L1X_SensorInit(dev); if(status) { APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X ultra low power Loading failed\n"); //HAL_Delay(100); return status; } APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X ultra low power ready ! \r\n"); /*********************************/ /* Sensor configuration */ /*********************************/ /* (Optional) Program sensor to raise an interrupt ONLY below 300mm */ //status = VL53L1X_SetInterruptConfiguration(dev, distance_threshold_mm, 1); //i_distance_threshold_mm status = VL53L1X_SetDistanceThreshold(dev, distance_threshold_mm,distance_threshold_mm, 0,1); //i_distance_threshold_mm /* (Optional) Program a 10Hz ranging frequency */ status = VL53L1X_SetInterMeasurementInMs(dev, inter_measurement_ms); // range_interval_ms /* Increase the macro timing. This is equivalent as increasing the integration time */ //status = VL53L1X_SetMacroTiming(dev, macro_timing); // micro_timing_ms status = VL53L1X_SetTimingBudgetInMs(dev, macro_timing); /* Enable all the SPADS */ status = VL53L1X_SetROI(dev, roi_width, roi_width); // SPADS { 1 -- 16 } if(range_mode != STS_TOF_LOW_POWER_RANGE) { /* Example for robust and short distance measurements. Max distance reduced * but very low number of false-positives */ status |= VL53L1X_SetSigmaThreshold(dev, sigma_mm); status |= VL53L1X_SetSignalThreshold(dev, signal_kcps); } /*********************************/ /* Ranging loop */ /*********************************/ status = VL53L1X_StartRanging(dev); if(status) { APP_LOG(TS_OFF,VLEVEL_L,"VL53L1X_ULP_StartRanging failed with status %u\n", status); return status; } APP_LOG(TS_OFF,VLEVEL_L,"Ranging started. Put your hand close to the sensor to generate an interrupt...\n"); loop = 0; while(loop < 20) { /* Use this external function to detect when a hardware interrupt is generated on PIN 7 (GPIO1). It means that a new measurement is ready. */ if(IsInterruptDetected(dev)) { /* (Mandatory) Clear HW interrupt to restart measurements */ VL53L1X_ClearInterrupt(dev); /* Dump debug data */ #if 0 status = VL53L1X_DumpDebugData(dev, &measurement_status, &estimated_distance_mm, &r_sigma_mm, &r_signal_kcps, &r_ambient_kcps); *ranged_distance = estimated_distance_mm; APP_LOG(TS_OFF,VLEVEL_L,"Target detected! Interrupt raised by sensor, Distance =%d mm \r\n", estimated_distance_mm ); #endif status = VL53L1X_GetDistance(dev, &estimated_distance_mm); APP_LOG(TS_OFF,VLEVEL_L,"Target detected! Interrupt raised by sensor, Distance =%d mm \r\n", estimated_distance_mm ); loop++; } } status = VL53L1X_StopRanging(dev); APP_LOG(TS_OFF,VLEVEL_L,"End of VL53L1X ultra low power demo\n"); return status; #endif } #endif /* * L8M */ /************************************************************/ /* VL53LMZ ULD motion indicator with detection thresholds */ /************************************************************/ /* * This example shows how to use the motion indicator with detection threshold. * This kind of configuration might be used for user detection applications. * To use this example, user needs to be sure that macro * VL53LMZ_DISABLE_MOTION_INDICATOR is NOT enabled (see file platform.h). */ #include #include #include #include "vl53l8cx_api.h" #include "vl53l8cx_plugin_motion_indicator.h" #include "vl53l8cx_plugin_detection_thresholds.h" VL53L8CX_Configuration Dev; /* Sensor configuration */ VL53L8CX_Motion_Configuration motion_config; /* Motion configuration*/ VL53L8CX_ResultsData Results; /* Results data from VL53LMZ */ // #define UNUSED(x) (void)(x) /* This function needs to be filled by the customer. It allows knowing when * the VL53LMZ interrupt is raised on GPIO1. This is the only way to use detection thresholds. */ /* int WaitForL5Interrupt(VL53LMZ_Configuration * pDev) { //Add your implementation here ... UNUSED(pDev); return 0; } */ //extern int WaitForL5Interrupt(VL53LMZ_Configuration * pDev); //extern int IntCount; int example11(void) { /*********************************/ /* VL53LMZ ranging variables */ /*********************************/ uint8_t status, loop, isAlive, isReady, i; #if 0 VL53L8CX_Configuration Dev; /* Sensor configuration */ VL53L8CX_Motion_Configuration motion_config; /* Motion configuration*/ VL53L8CX_ResultsData Results; /* Results data from VL53LMZ */ #endif /*********************************/ /* Customer platform */ /*********************************/ /* Fill the platform structure with customer's implementation. For this * example, only the I2C address is used. */ Dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS; /* (Optional) Reset sensor toggling PINs (see platform, not in API) */ //Reset_Sensor(&(Dev.platform)); /* (Optional) Set a new I2C address if the wanted address is different * from the default one (filled with 0x20 for this example). */ //status = vl53lmz_set_i2c_address(&Dev, 0x20); /*********************************/ /* Power on sensor and init */ /*********************************/ #if 0 /* (Optional) Check if there is a VL53LMZ sensor connected */ status = vl53lmz_is_alive(&Dev, &isAlive); if(!isAlive || status) { printf("VL53LMZ not detected at requested address\n"); return status; } #endif /* (Mandatory) Init VL53LMZ sensor */ status = vl53l8cx_init(&Dev); if(status) { printf("VL53LMZ ULD Loading failed\n"); return status; } //printf("VL53LMZ ULD ready ! (Version : %s)\n", // VL53LMZ_API_REVISION); /*********************************/ /* Program motion indicator */ /*********************************/ /* Create motion indicator with resolution 8x8 */ status = vl53l8cx_motion_indicator_init(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); if(status) { printf("Motion indicator init failed with status : %u\n", status); //return status; } /* (Optional) Change the min and max distance used to detect motions. The * difference between min and max must never be >1500mm, and minimum never be <400mm, * otherwise the function below returns error 127 */ //status = vl53l8cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 1000, 2000); status = vl53l8cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 2000, 2600); if(status) { printf("Motion indicator set distance motion failed with status : %u\n", status); //return status; } /* If user want to change the resolution, he also needs to update the motion indicator resolution */ status = vl53l8cx_set_resolution(&Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_motion_indicator_set_resolution(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); /* Set the device in AUTONOMOUS and set a small integration time to reduce power consumption */ status = vl53l8cx_set_resolution(&Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_set_ranging_mode(&Dev, VL53L8CX_RANGING_MODE_AUTONOMOUS); status = vl53l8cx_set_ranging_frequency_hz(&Dev, 10); status = vl53l8cx_set_integration_time_ms(&Dev, 10); /*********************************/ /* Program detection thresholds */ /*********************************/ /* In this example, we want 1 thresholds per zone for a 8x8 resolution */ /* Create array of thresholds (size cannot be changed) */ VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS]; /* Set all values to 0 */ memset(&thresholds, 0, sizeof(thresholds)); /* Add thresholds for all zones (64 zones in resolution 4x4, or 64 in 8x8) */ 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; /* The value 44 is given as example. All motion above 44 will be considered as a movement */ thresholds[i].param_low_thresh = 44; thresholds[i].param_high_thresh = 44; } /* The last thresholds must be clearly indicated. As we have 64 * checkers, the last one is the 63 */ thresholds[63].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[63].zone_num; /* Send array of thresholds to the sensor */ vl53l8cx_set_detection_thresholds(&Dev, thresholds); /* Enable detection thresholds */ vl53l8cx_set_detection_thresholds_enable(&Dev, 1); /*********************************/ /* Ranging loop */ /*********************************/ int IntCount = 0; status = vl53l8cx_start_ranging(&Dev); printf("Waiting for a movement into the FOV between 1m and 2m...\n"); #if 1 loop = 10; //while(loop < 11111) while(1) { /* Function WaitForL5Interrupt() does not exists, and must be * implemented by user. It allows catching the interrupt raised on * pin A3 (INT), when the checkers detect the programmed * conditions. */ // isReady = WaitForL5Interrupt(&Dev); isReady = ToF_EventDetected; if (ToF_EventDetected != 0) { vl53l8cx_get_ranging_data(&Dev, &Results); /* As the sensor is set in 8x8 mode by default, we have a total * of 64 zones to print. For this example, only the data of first zone are * print */ for(i = 0; i < 64; i++) { if(Results.motion_indicator.motion[motion_config.map_id[i]] >= 44) { printf(" Movement detected in this zone : %3d !\n", i); } } printf("\n"); loop++; } } status = vl53l8cx_stop_ranging(&Dev); printf("End of ULD demo\n"); //return status; #endif } int example11_init(void) { /*********************************/ /* VL53LMZ ranging variables */ /*********************************/ uint8_t status, loop, isAlive, isReady, i; #if 0 VL53L8CX_Configuration Dev; /* Sensor configuration */ VL53L8CX_Motion_Configuration motion_config; /* Motion configuration*/ VL53L8CX_ResultsData Results; /* Results data from VL53LMZ */ #endif /*********************************/ /* Customer platform */ /*********************************/ /* Fill the platform structure with customer's implementation. For this * example, only the I2C address is used. */ Dev.platform.address = VL53L8CX_DEFAULT_I2C_ADDRESS; /* (Optional) Reset sensor toggling PINs (see platform, not in API) */ //STS_Reset_Sensor(&(Dev.platform)); STS_Reset_Sensor(); /* (Optional) Set a new I2C address if the wanted address is different * from the default one (filled with 0x20 for this example). */ //status = vl53lmz_set_i2c_address(&Dev, 0x20); /*********************************/ /* Power on sensor and init */ /*********************************/ #if 0 /* (Optional) Check if there is a VL53LMZ sensor connected */ status = vl53lmz_is_alive(&Dev, &isAlive); if(!isAlive || status) { printf("VL53LMZ not detected at requested address\n"); return status; } #endif /* (Mandatory) Init VL53LMZ sensor */ status = vl53l8cx_init(&Dev); if(status) { printf("VL53LMZ ULD Loading failed\n"); return status; } else { printf("VL53L8CX ULD good\n"); } //printf("VL53LMZ ULD ready ! (Version : %s)\n", // VL53LMZ_API_REVISION); /*********************************/ /* Program motion indicator */ /*********************************/ /* Create motion indicator with resolution 8x8 */ status = vl53l8cx_motion_indicator_init(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); if(status) { printf("Motion indicator init failed with status : %u\n", status); //return status; } /* (Optional) Change the min and max distance used to detect motions. The * difference between min and max must never be >1500mm, and minimum never be <400mm, * otherwise the function below returns error 127 */ status = vl53l8cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 200, 400); //status = vl53l8cx_motion_indicator_set_distance_motion(&Dev, &motion_config, 2000, 2600); if(status) { printf("Motion indicator set distance motion failed with status : %u\n", status); //return status; } /* If user want to change the resolution, he also needs to update the motion indicator resolution */ status = vl53l8cx_set_resolution(&Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_motion_indicator_set_resolution(&Dev, &motion_config, VL53L8CX_RESOLUTION_8X8); /* Set the device in AUTONOMOUS and set a small integration time to reduce power consumption */ status = vl53l8cx_set_resolution(&Dev, VL53L8CX_RESOLUTION_8X8); status = vl53l8cx_set_ranging_mode(&Dev, VL53L8CX_RANGING_MODE_AUTONOMOUS); status = vl53l8cx_set_ranging_frequency_hz(&Dev, 10); status = vl53l8cx_set_integration_time_ms(&Dev, 10); /*********************************/ /* Program detection thresholds */ /*********************************/ /* In this example, we want 1 thresholds per zone for a 8x8 resolution */ /* Create array of thresholds (size cannot be changed) */ VL53L8CX_DetectionThresholds thresholds[VL53L8CX_NB_THRESHOLDS]; /* Set all values to 0 */ memset(&thresholds, 0, sizeof(thresholds)); /* Add thresholds for all zones (64 zones in resolution 4x4, or 64 in 8x8) */ 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; /* The value 44 is given as example. All motion above 44 will be considered as a movement */ thresholds[i].param_low_thresh = 44; thresholds[i].param_high_thresh = 44; } /* The last thresholds must be clearly indicated. As we have 64 * checkers, the last one is the 63 */ thresholds[63].zone_num = VL53L8CX_LAST_THRESHOLD | thresholds[63].zone_num; /* Send array of thresholds to the sensor */ vl53l8cx_set_detection_thresholds(&Dev, thresholds); /* Enable detection thresholds */ vl53l8cx_set_detection_thresholds_enable(&Dev, 1); /*********************************/ /* Ranging loop */ /*********************************/ int IntCount = 0; status = vl53l8cx_start_ranging(&Dev); printf("Waiting for a movement into the FOV between 1m and 2m...\n"); #if 1 loop = 0; while(loop < 100) //while(1) { printf("Waiting for a movement into the FOV between 1m and 2m...\n"); /* Function WaitForL5Interrupt() does not exists, and must be * implemented by user. It allows catching the interrupt raised on * pin A3 (INT), when the checkers detect the programmed * conditions. */ // isReady = WaitForL5Interrupt(&Dev); isReady = ToF_EventDetected; if(isReady) { vl53l8cx_get_ranging_data(&Dev, &Results); /* As the sensor is set in 8x8 mode by default, we have a total * of 64 zones to print. For this example, only the data of first zone are * print */ for(i = 0; i < 64; i++) { if(Results.motion_indicator.motion[motion_config.map_id[i]] >= 44) { printf(" Movement detected in this zone : %3d !\n", i); } } printf("\n"); loop++; } } status = vl53l8cx_stop_ranging(&Dev); printf("End of ULD demo\n"); //return status; #endif } void example11_process() { /*********************************/ /* Ranging loop */ /*********************************/ int IntCount = 0; int loop = 0; //while(loop < 1) //while(1) { /* Function WaitForL5Interrupt() does not exists, and must be * implemented by user. It allows catching the interrupt raised on * pin A3 (INT), when the checkers detect the programmed * conditions. */ // isReady = WaitForL5Interrupt(&Dev); if (ToF_EventDetected !=0) { ToF_EventDetected = 0; vl53l8cx_get_ranging_data(&Dev, &Results); /* As the sensor is set in 8x8 mode by default, we have a total * of 64 zones to print. For this example, only the data of first zone are * print */ for(uint8_t i = 0; i < 64; i++) { if(Results.motion_indicator.motion[motion_config.map_id[i]] >= 44) { printf(" Movement detected in this zone : %3d !\n", i); } } printf("\n"); //loop++; } } //status = vl53l8cx_stop_ranging(&Dev); //printf("End of ULD demo\n"); //return status; } /* * L8M */ #ifdef __cplusplus } #endif