WLE5CC_NODE_STS/STS/TOF/App/app_tof.c

882 lines
29 KiB
C

/**
******************************************************************************
* @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 <stdio.h>
#include "usart.h"
#include <stdlib.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"
#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<repeat; k++)
{
STS_TOF_L8_Process();
for (uint8_t i = 0; i < 64; i++)
{
/* Print distance and status */
if ((Result.ZoneResult[i].NumberOfTargets > 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])<sts_gesture_mask_off_height_cm*10){
fhmos_bg.maskoff[i] = 0;
} else {
fhmos_bg.maskoff[i] = 1;
}
sts_mask_bitmap[(uint8_t)(i/8)] |= (fhmos_bg.maskoff[i])<<(7-i%8);
if (i%8==0) printf("\r\n");
printf("|%4ld %4d ", range_distance, fhmos_bg.h2cm[i]);
}
else {
fhmos_bg.h2cm[i] += 0;
//printf(" .%d. ", i);
}
}
}
for (i=0; i<64; i++)
{
if (i%8==0) printf("\r\n");
printf("|%d ", (uint8_t)fhmos_bg.maskoff[i]);
}
for (i=0; i<8; i++)
printf("%02X\r\n",sts_mask_bitmap[i]);
#endif
}
void sts_generate_fall_gesture_map(void)
{
uint8_t i=0,head_xy=0;
uint32_t range_distance =0, sts_fall_head_position=8000; // assume max range 8000 mm, actual 4500mm
for (i=0; i<64; i++)
{
fhmos_gesture.h2cm[i] = 0;
fhmos_gesture.maskoff[i] = 0;
}
fhmos_gesture.head_level =1000; // 1000 mm
fhmos_gesture.head_xy = 31; //center of FOV
for (i=0;i<8;i++)
fhmos_gesture_bitmap[i]=0x0;
for (uint8_t i = 0; i < 64; i++)
{
if ((Result.ZoneResult[i].NumberOfTargets > 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])<sts_gesture_mask_off_height_cm*10)? 0:1;
fhmos_gesture_bitmap[(uint8_t)(i/8)] |= (fhmos_gesture.maskoff[i])<<(7-i%8);
// debug
if (i%8==0) printf("\r\n");
printf("|%4ld %4d ", range_distance, fhmos_gesture.h2cm[i]);
}
else {
fhmos_gesture.h2cm[i] = 0;
}
}
fhmos_gesture.head_level = 0xff&((sts_sensor_install_height - sts_fall_head_position)/10); // head level from floor in CM
fhmos_gesture.head_xy = head_xy&0xff;
#if 0
for (i=0; i<64; i++)
{
if (i%8==0) printf("\r\n");
printf("|%d ", (uint8_t)fhmos_gesture.maskoff[i]);
}
for (i=0; i<8; i++)
printf("%02X\r\n",fhmos_gesture_bitmap[i]);
#endif
sts_fhmos_bitmap_pending = 1;
printf("\r\n Fall Gesture bitmap Generated\r\n");
}
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)
uint32_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 k=0; k<10; k++)
{
STS_TOF_L8_Process();
// int status = VL53L8A1_RANGING_SENSOR_GetDistance(VL53L8A1_DEV_CENTER, &Result);
// printf("\r\n status =%d \r\n", status);
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 /=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 =%d", factor1, factor2);
sts_head_level_low = 0;
//if ((roi_distance < sts_sensor_install_height)&&(roi_distance < (sts_high_threshold - fhmos_cfg.th_head_level_height_cm*10))) // TODO XXX
if ((roi_distance < factor1)&& (roi_distance > 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