/** ****************************************************************************** * @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" #include #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" #include "yunhorn_sts_sensors.h" #include "sts_lamp_bar.h" volatile uint8_t fhmos_fall=0, fhmos_human_movement=0, fhmos_occupancy=0, fhmos_sos_alarm=0; volatile uint32_t fhmos_fall_counter=0; volatile uint32_t sts_low_threshold=1500, sts_high_threshold=2800, sts_occupancy_threshold=2300; extern volatile uint8_t sts_gesture_mask_off_height_cm; extern volatile uint8_t sts_head_level_low; volatile sts_fhmos_sensor_config_t fhmos_cfg={70,4,8,8,20,80,50,0}; volatile sts_fhmos_sensor_ambient_height_t fhmos_bg={0x0}, fhmos_gesture={0x0}, fhmos_net={0x0}; volatile sts_fhmos_sensor_data_t fhmos_data={0}; extern volatile uint8_t sts_fhmos_result; volatile uint8_t sts_mask_bitmap[8]={0x0}, fhmos_gesture_bitmap[8]={0x0}; extern volatile uint16_t sts_sensor_install_height; //in mm extern volatile uint8_t sts_lamp_bar_color; extern volatile uint8_t sts_status_color; extern volatile uint8_t sts_hall1_read,sts_hall2_read; // Above hall1_read == reed_hall_result, hall2_read == emergency_button extern volatile uint8_t sts_pir_read; extern volatile uint8_t sts_fhmos_state_changed; extern volatile uint8_t sts_fhmos_bitmap_pending; #endif #include "stm32wlxx_nucleo.h" /* 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 (600U) #define HIGH_THRESHOLD (2000U) // floor, eg. 2200 #define OCCUPANCY_THRESHOLD (1500) // assume high people 2000-450 = 1550 /* ceiling -------------------- zero - 00 ref. 3000 mm high * * * people high --------------- 2100 mm high people * * * * * people low ------------------- 900 mm child normal * * * * other things ----------------- 400 mm * * * floor ----------------------00000 * * */ /* 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 VL53L8CX_Configuration Dev; static void MX_53L8A1_ThresholdDetection_Init(void); static void MX_53L8A1_ThresholdDetection_Process(void); static void print_result(RANGING_SENSOR_Result_t *Result); //static void sts_generate_fall_gesture_map(void); #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(); STS_FHMOS_sensor_config_init(); #elif defined(STS_R1D) XWL55_WLE5_53L0X_Init(); #endif /* USER CODE BEGIN TOF_Init_PostTreatment */ /* USER CODE END TOF_Init_PostTreatment */ } /* * LM background task */ void STS_LMZ_Ambient_Height_Scan_Process(void) { #if 1 uint8_t i=0, repeat=1; uint32_t range_distance =0; for (i=0; i<64; i++) { fhmos_bg.h2cm[i] = 0; fhmos_bg.maskoff[i] = 0; } for (i=0;i<8;i++) sts_mask_bitmap[i] =0x0; // printf("sts sensor install height = %4d \r\n", (int)sts_sensor_install_height); sts_high_threshold = sts_sensor_install_height; sts_low_threshold = sts_sensor_install_height-1400; STS_TOF_L8_Reconfig(); //printf("%c[2H", 27); /* clear screen */ for (uint8_t k=0; k 0)) { range_distance = (uint32_t)Result.ZoneResult[i].Distance[0]; //if (sts_sensor_install_height > range_distance) fhmos_bg.h2cm[i] += ((uint32_t)sts_sensor_install_height - range_distance); if (abs(fhmos_bg.h2cm[i]) 0) && (fhmos_bg.maskoff[i]==0)) { range_distance = (uint32_t)Result.ZoneResult[i].Distance[0]; if (range_distance < sts_fall_head_position) { sts_fall_head_position = range_distance; // simply find out the head level head_xy = i; // head x, y coordination in 8x8 matrix } fhmos_gesture.h2cm[i] = (uint16_t)abs(sts_sensor_install_height - range_distance); fhmos_gesture.maskoff[i]= ((fhmos_gesture.h2cm[i]) 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 /=40; 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(); //printf("\r\n Tof Process\r\n"); //STS_TOF_L8_Process(); #endif /* USER CODE BEGIN TOF_Process_PostTreatment */ /* USER CODE END TOF_Process_PostTreatment */ } #ifdef L8 void STS_TOF_L8_Init(void) { MX_53L8A1_ThresholdDetection_Init(); MX_53L8A1_ThresholdDetection_Process(); } void STS_TOF_L8_Process(void) { //while (1) { /* interrupt mode */ if (ToF_EventDetected != 0) { ToF_EventDetected = 0; #if 1 if (STS_Status_Door_Close == sts_hall1_read) { status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result); //printf("\r\n status =%d \r\n", status); if (status == BSP_ERROR_NONE) { print_result(&Result); } else { printf("\r\n x \r\n"); } } #endif } } } void STS_TOF_L8_Reconfig(void) { MX_53L8A1_ThresholdDetection_ConfigIT(sts_low_threshold, sts_high_threshold); } /* 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); } } void MX_53L8A1_ThresholdDetection_ConfigIT(uint32_t low_threshold, uint32_t high_threshold) { RANGING_SENSOR_ITConfig_t ITConfig; status = VL53L8A1_RANGING_SENSOR_Stop(VL53L8A1_DEV_CENTER); /* 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); 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); } } 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); 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); } #if 0 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); #endif #if 0 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; //static uint8_t prev_occupy_state=0; uint32_t center_range_distance=0; uint8_t center_roi[4] = {27,28,35,36}; static uint32_t prev_distance[64]={0}; uint32_t motion_diff=0, motion_power=0; //uint32_t motion_power_threshold = 3200; // 64*50mm //SysTime_t sensor_event_time = SysTimeGetMcuTime(); // uint32_t time_stamp=STS_Get_Date_Time_Stamp(); //printf("\r\n Motion level Calculation \r\n"); for (j=0; j<64; j++) { if (prev_distance[j] > (uint32_t)Result->ZoneResult[j].Distance[0]) motion_diff = (prev_distance[j] - (uint32_t)Result->ZoneResult[j].Distance[0]); else motion_diff = (uint32_t)Result->ZoneResult[j].Distance[0] - prev_distance[j]; //printf("\r\nj=%d, diff=%d ", j, motion_diff); motion_power += motion_diff; prev_distance[j] = (uint16_t)Result->ZoneResult[j].Distance[0]; } motion_power /=64; if (motion_power > fhmos_cfg.th_motion_power_level) { fhmos_human_movement =1; } else { fhmos_human_movement =0; } #if 0 printf("\r\n Motion Power =%d Average=%d Human Movement =%d, th=%d \r\n", motion_power*64, motion_power, fhmos_human_movement, fhmos_cfg.th_motion_power_level); #endif #if 0 zones_per_line = ((Profile.RangingProfile == RS_PROFILE_8x8_AUTONOMOUS) || (Profile.RangingProfile == RS_PROFILE_8x8_CONTINUOUS)) ? 8 : 4; #endif //printf("%c[2H", 27); /* clear screen */ for (i=0; i<4; i++) { center_range_distance +=(uint32_t)(Result->ZoneResult[center_roi[i]].Distance[0]); } //printf("\n\r Center Range =%4d mm\r\n",center_range_distance ); //int32_t roi_distance =(uint32_t)(Result->ZoneResult[j + k].Distance[l]); int32_t roi_distance =(uint32_t)center_range_distance/4; uint32_t factor1 = sts_sensor_install_height; uint32_t factor2 = (sts_high_threshold - 10*fhmos_cfg.th_head_level_height_cm); /* state tree */ //printf("\r\n th_head_level_cm=%d, factor2=high_th:%d - mm:%d\r\n", fhmos_cfg.th_head_level_height_cm, sts_high_threshold, factor2); //printf("\r\n roi_D < Facot1 =%d , D factor2)) { //printf("\r\nThreshold: low =%d occupy=%d head level=%d high=%d\r\n", sts_low_threshold, sts_occupancy_threshold, fhmos_cfg.th_head_level_height_cm*10, sts_high_threshold); printf("\r\n YELLOW OR RED Distance=%ld \r\n", roi_distance); sts_head_level_low = 1; #if 0 fhmos_data.state_fall = STS_FHMOS_FALL_STATE_POTENTIAL; fhmos_data.color_fall = STS_FALL_SUSPICIOUS_COLOR; printf("\r\n State Fall =%d \r\n", fhmos_data.state_fall); #endif //sts_fhmos_state_changed |=1; } else if ((roi_distance < factor2)) // TODO XXX { sts_head_level_low = 0; fhmos_data.state_fall = STS_FHMOS_FALL_STATE_NORMAL; sts_fhmos_bitmap_pending = 0; //fhmos_data.color_fall = STS_FALL_NORMAL_COLOR; // HOLD THIS COLOR BEFORE ENTER YELLOW STATUS //printf("\r\n NORMAL NO FALL Distance=%4ld COLOR =%d \r\n", roi_distance, fhmos_data.color_fall); } OnSensorL8AStateChanged(); //sts_fhmos_result = 1; //STS_Combined_Status_Processing(); } #endif #ifdef L8 /* Represent Color Value Definition * Fall Blue 0 The Room is not occupied by Human * Green 1 Human in room in normal level (head above 700 mmH from floor level) * Yellow 2 Human in low level position for short time potential (Head below 700mmH from floor level * Red 3 Human in low level position with time longer than threshold, e.g. 4 mins.(Head below 700 mm from Floor level * Human * Movement Blue 0 The Room is not occupied by Human * Green 1 The room is occupied by human, with movement * Yellow 2 The room is occupied by human, with motionless for short period of time (???) * Red 3 The room is occupied by human, with motionless for a period of time longer than threshold period, e.g. 5min. * * Occupancy Blue 0 The room is not occupied by Human * Green 1 The room is occupied by human, with movement * Red 2 The room is occupied by human, for a short period of time (???) * * # height is configurable from 10cm to 90 cm, with interval of 1cm * # the period of time is configurable, from 1 min to 30 mins, with 15 sec as interval * * sts_height_threshold (10cm --90 cm, 1cm interval) (10cm=10, 90cm=90, "P11T1XXX" * sts_fall_duration_threshold_potential (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T2XXX" * sts_fall_duration_threshold_confirm (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T3XXX" * * sts_motionless_threshold_short (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T4XXX" * sts_motionless_threshold_long (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T5XXX" * * sts_occupancy_threshold_overstay (1 min to 30 min. 15 sec interval, 1800 sec. 1800=15*120, 60=15*4) "P11T6XXX" * */ void STS_FHMOS_sensor_read(sts_fhmos_sensor_data_t *sts_data) { //uint8_t fhmos_fall=0, fhmos_human_movement=0, fhmos_occupancy=0, fhmos_sos_alarm=0; sts_data->state_occupancy = fhmos_data.state_occupancy; sts_data->state_fall = fhmos_data.state_fall; sts_data->state_human_movement = fhmos_data.state_human_movement; sts_data->state_sos_alarm = fhmos_data.state_sos_alarm; sts_data->lamp_bar_color = sts_lamp_bar_color; sts_data->state_hall_1 = sts_hall1_read; sts_data->state_hall_2 = sts_hall2_read; sts_data->state_PIR = sts_pir_read;; //sts_data->state_PIR = fhmos_data.state_PIR; } #endif #if defined(STS_P2)||defined(STS_T6)||defined(L8) 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_M,"############### 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 #ifdef __cplusplus } #endif