/* USER CODE BEGIN Header */ /** ****************************************************************************** * @file yunhorn_sts_process.c * * @author Yunhorn (r) Technology Limited Application Team * * @brief Yunhorn (r) SmarToilets (r) Product configuration file. * ****************************************************************************** * @attention * * Copyright (c) 2022 Yunhorn Technology Limited. * Copyright (c) 2022 Shenzhen Yunhorn Technology Co., Ltd. * 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. * ****************************************************************************** */ /* USER CODE END Header */ /* Includes ------------------------------------------------------------------*/ #include "stdint.h" #include "platform.h" #include "sys_conf.h" #include "sys_app.h" #include "stdio.h" #include "stm32_systime.h" #include "adc_if.h" #include "gpio.h" #include "LmHandler.h" //#include "app_tof.h" #include "lora_app.h" #include "yunhorn_sts_prd_conf.h" #include "yunhorn_sts_sensors.h" #include "sts_cmox_hmac_sha.h" /* USER CODE BEGIN Includes */ extern volatile sts_cfg_nvm_t sts_cfg_nvm; extern volatile uint8_t sts_ac_code[20]; volatile uint8_t sts_service_mask=0; volatile uint32_t rfac_timer; volatile uint8_t sensor_data_ready=0; extern volatile uint8_t sts_reed_hall_result; volatile uint8_t last_sts_reed_hall_result; volatile uint8_t sts_soap_level_state; volatile STS_OO_SensorStatusDataTypeDef sts_o7_sensorData; volatile STS_PRESENCE_SENSOR_Event_Status_t sts_o7_event_status; volatile float sts_distance_rss_distance, sts_sensor_install_height=0;//in mm extern volatile float sts_presence_rss_distance, sts_presence_rss_score; extern volatile uint8_t sts_hall1_read,sts_hall2_read; volatile uint8_t sts_reed_hall_1_result=STS_Status_Door_Open,sts_reed_hall_2_result=STS_Status_SOS_Release, last_sts_reed_hall_1_result=STS_Status_Door_Open, last_sts_reed_hall_2_result=STS_Status_SOS_Release; volatile uint8_t sts_reed_hall_1_changed=0, sts_reed_hall_2_changed=0; volatile uint8_t sts_rss_config_updated_flag = 0; extern volatile uint8_t mems_int1_detected, link_wakeup, link_sleep; volatile uint32_t event_start_time=0, event_stop_time=0; volatile uint32_t event_door_lock_start_time=0,event_door_lock_stop_time=0; extern volatile uint8_t sts_occupancy_overtime_state; //extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; extern volatile sts_cfg_nvm_t sts_cfg_nvm; extern volatile uint8_t sts_fall_detection_acc_threshold, sts_fall_detection_depth_threshold, sts_occupancy_overtime_threshold_in_10min; extern volatile uint8_t sts_fall_rising_detected_result_changed_flag; extern volatile uint8_t last_sts_fall_rising_detected_result; extern volatile uint8_t sts_unconscious_state; extern volatile uint16_t sts_unconscious_threshold, sts_unconscious_duration; extern volatile uint8_t sts_emergency_button_pushed, sts_rss_2nd_result,sts_tof_result, sts_status_color, sts_lamp_bar_color, sts_service_mask; extern volatile distance_measure_cfg_t distance_cfg; extern uint8_t sts_fall_rising_detected_result; extern volatile uint16_t sts_fall_rising_pattern_factor1; extern volatile uint16_t sts_roc_acc_standard_variance; extern uint8_t luminance_level; SysTime_t mems_event_time; volatile uint32_t last_sts_rss_time_stamp=0; extern volatile uint8_t sts_reed_hall_ext_int; volatile uint8_t sts_occupancy_status; volatile uint8_t sts_hall1_changed_flag=0, sts_hall2_changed_flag=0, last_sts_hall1_result=0, last_sts_hall2_result=0; volatile uint8_t sts_reed_hall_changed_flag = 0; extern volatile uint8_t sts_reed_hall_result; volatile uint8_t sts_water_leakage_result=0; volatile uint8_t sts_water_leakage_changed_flag=0; //extern volatile uint8_t sensor_data_ready; #ifdef YUNHORN_STS_R4_ENABLED volatile STS_R0_SensorDataTypeDef r4_data; #endif #ifdef YUNHORN_STS_O5_ENABLED #endif #if defined(STS_O7)||defined(STS_O6) extern volatile uint8_t motion_detected_count; extern volatile uint8_t motion_in_hs_zone[12][10]; //0.4*12=4.8meter high, past 10 measures extern volatile uint8_t detected_hs_zone; extern volatile STS_OO_RSS_SensorTuneDataTypeDef sts_presence_rss_config; volatile uint32_t cnt=0; extern volatile distance_measure_cfg_t distance_cfg; volatile uint8_t sts_work_mode = STS_DUAL_MODE; extern uint8_t luminance_level; extern volatile uint8_t sts_status_color; extern volatile uint8_t sts_lamp_bar_color; //puColor extern volatile uint8_t sts_cloud_netcolor; //netColor extern volatile bool p2_work_finished; volatile uint8_t sts_tof_result_changed_flag = 0; volatile uint8_t sts_rss_result_changed_flag = 0; volatile uint8_t sts_rss_result = STS_RESULT_NO_MOTION; volatile uint8_t sts_rss_2nd_result = STS_RESULT_NO_MOTION; //2nd RSS sensor status volatile uint8_t sts_tof_result = STS_RESULT_NO_MOTION; volatile uint8_t last_sts_rss_result=STS_RESULT_NO_MOTION; //extern volatile uint8_t last_sts_reed_hall_result; extern volatile uint8_t last_lamp_bar_color; extern volatile float sts_presence_rss_distance; char sts_presence_fall_detection_message[10][20]={ "State_Normal", "State_Fall_Down", "State_Rising_Up", "State_Laydown", "State_Unconscious", "State_StayStill" }; #endif /* // UTIL_SEQ_SetTask((1 << CFG_SEQ_Task_YunhornSTSEventP4), CFG_SEQ_Prio_0); // P1 --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE // P2 --- SEE ABOVE, RSS PRESENCE // P3 ----LAMP BAR SCOLLER PROCESS // P4 --- TOF DISTANCE VL53L0X simple distance // P5 --- TOF IN OUT COUNT VL53L3X in out or duration // P6 --- SOAP Level, capacitive measurement // P7 --- UltraSonic, 2nd wave UltraSonic range measure // P8 --- AIR QUALITY AND ODOR LEVEL, SMOKING DETECTION */ /* USER CODE END Includes */ /* External variables ---------------------------------------------------------*/ /* USER CODE BEGIN EV */ /* USER CODE END EV */ /* Private typedef -----------------------------------------------------------*/ /* USER CODE BEGIN PTD */ /* USER CODE END PTD */ /* Private define ------------------------------------------------------------*/ /* USER CODE BEGIN PD */ /* USER CODE END PD */ /* Private macro -------------------------------------------------------------*/ /* USER CODE BEGIN PM */ /* USER CODE END PM */ /* Private variables ---------------------------------------------------------*/ /* USER CODE BEGIN PV */ /* USER CODE END PV */ /* Private function prototypes -----------------------------------------------*/ /* USER CODE BEGIN PFP */ #if (defined(YUNHORN_STS_O6_ENABLED) && defined(USE_ACCONEER_A111)) #endif /* USER CODE END PFP */ /* Exported functions --------------------------------------------------------*/ void STS_YunhornAuthenticationCode_Process(void) { if ((sts_ac_code[0] == 0x00) && (sts_ac_code[19]== 0x0)) { APP_LOG(TS_OFF,VLEVEL_M, "Initial AC CODE blank... \r\n"); return; } sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0; if (sts_service_mask == STS_SERVICE_MASK_L2) { sts_ac_code[0] = 0x0; sts_ac_code[19]= 0x0; } APP_LOG(TS_OFF, VLEVEL_H, "STS_SERVICE_MASK:%d \r\n",sts_service_mask); } void STS_YunhornSTSEventRFAC_Process(void) { if ((sts_ac_code[0] ==0x0)&& (sts_ac_code[19]== 0x0)) { if ((rfac_timer >= STS_BURN_IN_RFAC) && (rfac_timer < (STS_BURN_IN_RFAC +3))) { APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------RFAC Process\r\n"); STS_SENSOR_Upload_Message(LORAWAN_USER_APP_CTRL_REPLY_PORT, 4, (uint8_t *)"RFAC"); } if ((rfac_timer > (STS_BURN_IN_RFAC + 2))) { APP_LOG(TS_OFF, VLEVEL_M, "\r\n -------------------Verify RFAC Success or Not\r\n"); sts_service_mask = (sts_hmac_verify()!= 0)? STS_SERVICE_MASK_L2:STS_SERVICE_MASK_L0; if (sts_service_mask == STS_SERVICE_MASK_L2) { sts_ac_code[0] = 0x0; sts_ac_code[19] = 0x0; } } } } /* * STS-P1 --- REEDSWITCH, HALL ELEMENT, WATER LEAKAGE */ void STS_YunhornSTSEventP1_Process(void) { if (sts_reed_hall_1_changed) { sts_reed_hall_1_result = HALL1_STATE; //sts_hall1_read; sts_reed_hall_1_changed =0; last_sts_reed_hall_1_result = sts_reed_hall_1_result; } if (sts_reed_hall_2_changed){ sts_reed_hall_2_result = HALL2_STATE;// sts_hall2_read; sts_reed_hall_2_changed =0; last_sts_reed_hall_2_result = sts_reed_hall_2_result; } STS_Combined_Status_Processing(); } extern volatile uint32_t wcnt; /* * STS-P2 --- RSS PRESENCE */ void STS_YunhornSTSEventP2_Process(void) { p2_work_finished=false; //STS_Lamp_Bar_Refresh(); //TODO XXX eliminate refresh every second.... try if ((sts_work_mode >= STS_RSS_MODE) && (sts_work_mode <= STS_TOF_RSS_MODE)) { sts_presence_rss_fall_rise_detection(); sts_rss_result_changed_flag = (sts_rss_result == last_sts_rss_result)? 0:1; last_sts_rss_result = sts_rss_result; sts_fall_rising_detected_result_changed_flag = (sts_fall_rising_detected_result == last_sts_fall_rising_detected_result)?0:1; last_sts_fall_rising_detected_result = sts_fall_rising_detected_result; if (sts_service_mask > 0 ) { sts_rss_result_changed_flag =0; sts_reed_hall_changed_flag = 0; sts_fall_rising_detected_result_changed_flag =0; } STS_Combined_Status_Processing(); } p2_work_finished=true; } void STS_Reed_Hall_Presence_Detection(void) { // HAL_Delay(50); // BOUNCING ELIMIATION sts_reed_hall_1_result = (sts_hall1_read==0)?STS_Status_Door_Close:STS_Status_Door_Open; sts_reed_hall_2_result = (sts_hall2_read==0)?STS_Status_Door_Close:STS_Status_Door_Open; //sts_reed_hall_result = ((STS_Reed_Hall_State)&STS_Status_Door_Open); // HAL_Delay(20); // BOUNCING ELIMIATION sts_reed_hall_changed_flag = 0; sts_reed_hall_ext_int = 0; } /* * STS P3 process, Lamp Bar Scoller */ void STS_YunhornSTSEventP3_Process(void) { #if (defined(STS_O6) ||defined(STS_O7)) if (STS_Reed_Hall_State == STS_Status_Door_Open) { sts_lamp_bar_color =STS_GREEN; } else { sts_lamp_bar_color =STS_RED; } STS_Lamp_Bar_Scoller(sts_lamp_bar_color, luminance_level); #endif } /* * STS SOAP Level detection Process, STS_CAP_Sensor_Detection Process * STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms * HAL_Delay(1000) (ms) * STS_CAP_Read_Data() Read STS_CAP_DATA state * STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage */ /* * STS-P4 Detection ToF distance (VL53L0X) * */ void STS_YunhornSTSEventP4_Process(void) { STS_SENSOR_Power_ON(0); #ifdef LED_ONBOARD LED_ON; HAL_Delay(10); LED_OFF; #endif #if defined(TOF_1)||defined(TOF_2) APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF_1, TOF_2 RANGING Process\r\n"); STS_TOF_VL53L0X_Range_Process(); #endif #ifdef TOF_3 APP_LOG(TS_OFF, VLEVEL_H, "\r\n TOF 3 RANGING Process ---- TOF250 Ranging \r\n"); STS_TOF250_Range_Process(); #endif STS_SENSOR_Power_OFF(0); } /* * STS P5 Process, Detection ToF IN-OUT PEOPLE COUNT (VL53L3X) * */ void STS_YunhornSTSEventP5_Process(void) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n P5 Testing Process\r\n"); } /* * STS-P6 --- SOAP Level, capacitive measurement * STS Soap Level Detection Process, STS_CAP_Sensor_Detection Process * STS_CAP_SWITCH(ON) Boost Voltage to 5V, then hold for 1000 ms * HAL_Delay(1000) (ms) * STS_CAP_Read_Data() Read STS_CAP_DATA state * STS_CAP_SWITCH(OFF) Switch Off Boosted Voltage */ void STS_YunhornSTSEventP6_Process(void) { APP_LOG(TS_OFF, VLEVEL_H, "\r\n P6 Testing Process\r\n"); STS_SENSOR_Power_ON(0); HAL_Delay(50); #ifdef LED_ONBOARD LED_ON; HAL_Delay(20); LED_OFF; #endif /* 1. Sensor Power On */ #if defined(SOAP_LEVEL_SENSOR) HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_SET); HAL_Delay(1000); /* 2. Read sensor state */ sts_soap_level_state = HAL_GPIO_ReadPin(SOAP_STATUS_GPIO_Port,SOAP_STATUS_Pin); APP_LOG(TS_OFF, VLEVEL_L, "\r\n Soap State = %s \r\n", (sts_soap_level_state==0x0)?" +++ Liquid Detected":" --- No Liquid"); HAL_GPIO_WritePin(SOAP_SWITCH_GPIO_Port, SOAP_SWITCH_Pin, GPIO_PIN_RESET); if (sts_soap_level_state == 0x0) { #ifdef LED_ONBOARD LED_ON; HAL_Delay(20); LED_OFF; #endif } #endif /* 3. Sensor Power Off */ STS_SENSOR_Power_OFF(0); } /* * STS P7 Process, Detection IAQ Sensors * air quality and odor level sensors */ void STS_YunhornSTSEventP7_Process(void) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n P7 Testing Process\r\n"); STS_SENSOR_Power_ON(0); STS_SENSOR_Power_OFF(0); } /* * STS P8 Process, Detection ETR Sensors, Water flow sensors, pulse counting * PA5 sensors , TIM2_ETR, STS-M4 */ void STS_YunhornSTSEventP8_Process(void) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n P8 Testing Process\r\n"); } /* * STS P_IO_RS485 Process, Send Out Sensor Data Via RS485 interface * sensors */ void STS_YunhornSTSEventPIORS485_Process(void) { APP_LOG(TS_OFF, VLEVEL_L, "\r\n P_IO_RS485 Process\r\n"); } void STS_PRESENCE_SENSOR_WakeUp_Process_Sampling(void) { #if 0 if ((sensor_data_ready ==0)) { STS_PRESENCE_SENSOR_GetValue(); } #endif } void STS_PRESENCE_SENSOR_After_Wake_Up() { } void STS_FallDetection_LampBarProcess(void) { } void STS_YunhornSTSFallDetection(void) { //APP_LOG(TS_OFF, VLEVEL_M, "\r\n YUNHORN STS FALL DETECTION \r\n"); //STS_YunhornCheckStandardDeviation(); } void STS_PRESENCE_SENSOR_NVM_CFG(void) { sts_presence_rss_config.default_start_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); sts_presence_rss_config.default_length_m = (float)((float)sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); sts_presence_rss_config.default_threshold = (float)((float)sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); sts_presence_rss_config.default_receiver_gain = (float)((float)sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); sts_presence_rss_config.default_zone_length_m = DEFAULT_ZONE_LENGTH; sts_presence_rss_config.default_profile = (float)(sts_cfg_nvm.p[RSS_CFG_PROFILE]); sts_presence_rss_config.default_update_rate_tracking = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_TRACKING]); sts_presence_rss_config.default_update_rate_presence = (float)(sts_cfg_nvm.p[RSS_CFG_RATE_PRESENCE]); sts_presence_rss_config.default_hwaas = (float)(sts_cfg_nvm.p[RSS_CFG_HWAAS]); sts_presence_rss_config.default_nbr_removed_pc = (float)(sts_cfg_nvm.p[RSS_CFG_NBR_REMOVED_PC]); //filter parameter sts_presence_rss_config.default_inter_frame_deviation_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_DEVIATION]*0.1f); sts_presence_rss_config.default_inter_frame_fast_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_FAST_CUTOFF]); sts_presence_rss_config.default_inter_frame_slow_cutoff = (float)(sts_cfg_nvm.p[RSS_CFG_ITE_SLOW_CUTOFF]*0.01f); sts_presence_rss_config.default_intra_frame_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_TIME]); sts_presence_rss_config.default_intra_frame_weight = (float)(sts_cfg_nvm.p[RSS_CFG_ITR_WEIGHT]*0.1f); sts_presence_rss_config.default_output_time_const = (float)(sts_cfg_nvm.p[RSS_CFG_OUTPUT_TIME]*0.1f); //filter parameter sts_presence_rss_config.default_downsampling_factor = (float)(sts_cfg_nvm.p[RSS_CFG_DOWNSAMPLING_FACTOR]); sts_presence_rss_config.default_power_save_mode = (float)(sts_cfg_nvm.p[RSS_CFG_POWER_MODE]); sts_rss_config_updated_flag = STS_RSS_CONFIG_FULL; //set to 2 for FULL config effect in next detection } void STS_PRESENCE_SENSOR_NVM_CFG_SIMPLE(void) { sts_presence_rss_config.default_start_m = (float)(sts_cfg_nvm.p[RSS_CFG_START_M]*0.1f); sts_presence_rss_config.default_length_m = (float)(sts_cfg_nvm.p[RSS_CFG_LENGTH_M]*0.1f); sts_presence_rss_config.default_threshold = (float)(sts_cfg_nvm.p[RSS_CFG_THRESHOLD]*0.1f); sts_presence_rss_config.default_receiver_gain = (float)(sts_cfg_nvm.p[RSS_CFG_RECEIVER_GAIN]*0.01f); sts_rss_config_updated_flag = STS_RSS_CONFIG_SIMPLE; //set to 1 for simple config effect in next detection } void STS_PRESENCE_SENSOR_Init_Send_Data(void) { sts_o7_sensorData.lamp_bar_color = STS_GREEN; sts_o7_sensorData.workmode = sts_work_mode; //STS_DUAL_MODE; sts_o7_sensorData.state_sensor1_on_off = 0x0; sts_o7_sensorData.state_sensor2_on_off = 0x0; sts_o7_sensorData.state_sensor3_on_off = 0x0; sts_o7_sensorData.state_sensor4_on_off = 0x0; sts_o7_sensorData.rss_presence_distance = 0x0; sts_o7_sensorData.rss_presence_score = 0x0; sts_o7_sensorData.fall_state = STS_PRESENCE_NORMAL; sts_o7_sensorData.fall_speed = 0x0; sts_o7_sensorData.fall_gravity = 0x0; sts_o7_sensorData.over_stay_state = 0x0; sts_o7_sensorData.over_stay_duration = 0x0; sts_o7_sensorData.unconscious_state = 0x0; sts_o7_sensorData.unconscious_duration = 0x0; sts_o7_sensorData.no_movement_duration = 0x0; sts_o7_sensorData.event_sensor1_start_time = 0x0; sts_o7_sensorData.event_sensor1_duration = 0x0; sts_o7_sensorData.event_sensor2_start_time = 0x0; sts_o7_sensorData.event_sensor2_duration = 0x0; sts_o7_sensorData.event_sensor3_motion_start_time = 0x0; sts_o7_sensorData.event_sensor3_motion_duration = 0x0; sts_o7_sensorData.event_sensor3_fall_start_time = 0x0; sts_o7_sensorData.event_sensor3_fall_duration = 0x0; sts_o7_sensorData.event_sensor4_start_time = 0x0; sts_o7_sensorData.event_sensor4_duration = 0x0; sts_o7_sensorData.battery_Pct = 99; // 99% as init value sts_o7_sensorData.dutycycletimelevel = 1; sensor_data_ready = 0; } void STS_PRESENCE_SENSOR_Prepare_Send_Data(STS_OO_SensorStatusDataTypeDef *sensor_data) { sensor_data->lamp_bar_color = sts_lamp_bar_color; sensor_data->workmode = sts_work_mode; sensor_data->state_sensor1_on_off = HALL1_STATE;//sts_hall1_read; //sts_hsts_reed_hall_result; // sts_hall1_read sensor_data->state_sensor2_on_off = sts_rss_result; sensor_data->state_sensor3_on_off = HALL2_STATE;//sts_hall2_read; //sts_emergency_button_pushed; //sts_hall2_read sensor_data->state_sensor4_on_off = sts_rss_2nd_result; if (sts_rss_result == STS_RESULT_MOTION) { sensor_data->rss_presence_distance = (uint16_t)(sts_presence_rss_distance)&0xFFFF; sensor_data->rss_presence_score = (uint16_t)(sts_presence_rss_score)&0xFFFF; // uint8_t sts_unconscious_state; // uint16_t sts_unconscious_threshold, sts_unconscious_threshold_duration; } else { sensor_data->rss_presence_distance = 0x0; sensor_data->rss_presence_score = 0x0; } sensor_data->unconscious_state=(sts_fall_rising_detected_result == STS_PRESENCE_UNCONSCIOUS)? 1:0; sensor_data->over_stay_state = sts_o7_sensorData.over_stay_state; sensor_data->over_stay_duration = sts_o7_sensorData.event_sensor1_duration; // no_movement or unconcious duration sensor_data->unconscious_duration = sts_o7_sensorData.event_sensor3_unconcious_duration; sensor_data->no_movement_duration = sts_o7_sensorData.event_sensor3_no_movement_duration; APP_LOG(TS_OFF,VLEVEL_L,"\r\n ... Over Stay Duration = %u Sec [Threshold: %u Seconds]\r\n", sensor_data->over_stay_duration, sts_occupancy_overtime_threshold_in_10min*60); sensor_data->fall_state = sts_fall_rising_detected_result; if (sts_fall_rising_detected_result == STS_PRESENCE_FALL) { APP_LOG(TS_OFF, VLEVEL_M, "\r\n......FALL RISING DETECTION RESULT: %25s \r\n",(char*)sts_presence_fall_detection_message[sts_fall_rising_detected_result] ); sensor_data->fall_speed = (uint8_t)sts_fall_rising_pattern_factor1; sensor_data->fall_gravity = (uint8_t)sts_roc_acc_standard_variance; } else { sensor_data->fall_speed = 0; sensor_data->fall_gravity = 0; } // For occupancy over time process //SysTime_t occupy_check_time = SysTimeGetMcuTime(); if ((sts_occupancy_overtime_threshold_in_10min != 0) && (event_start_time !=0)) { if (sts_occupancy_overtime_state == 1U) { sts_status_color = STS_RED_BLUE; sts_lamp_bar_color = STS_RED_BLUE; } //STS_Lamp_Bar_Refresh(); } sensor_data_ready = 1; } /** * @brief Initializes the motion sensors * @param Instance Motion sensor instance * @param Functions Motion sensor functions. Could be : * - MOTION_ACCELERO for instance * @retval BSP status */ void STS_PRESENCE_SENSOR_Init(void) { APP_LOG(TS_ON, VLEVEL_M, "##### YunHorn SmarToilets(r) Presence Sensor Started\r\n"); sts_o7_sensorData.workmode = (uint8_t)sts_work_mode; //STS_DUAL_MODE; sts_o7_sensorData.lamp_bar_color = (uint8_t)STS_GREEN; sts_o7_sensorData.battery_Pct = 99; sts_o7_sensorData.dutycycletimelevel = 1; sts_o7_sensorData.event_sensor1_start_time = 0; sts_o7_sensorData.event_sensor1_stop_time = 0; sts_o7_sensorData.event_sensor1_duration = 0; sts_o7_sensorData.event_sensor2_start_time = 0; sts_o7_sensorData.event_sensor2_stop_time = 0; sts_o7_sensorData.event_sensor2_duration = 0; sts_o7_sensorData.event_sensor3_motion_start_time = 0; sts_o7_sensorData.event_sensor3_motion_stop_time = 0; sts_o7_sensorData.event_sensor3_motion_duration = 0; sts_o7_sensorData.event_sensor3_fall_start_time = 0; sts_o7_sensorData.event_sensor3_fall_stop_time = 0; sts_o7_sensorData.event_sensor3_fall_duration = 0; sts_o7_sensorData.event_sensor4_start_time = 0; sts_o7_sensorData.event_sensor4_stop_time = 0; sts_o7_sensorData.event_sensor4_duration = 0; sts_o7_sensorData.over_stay_state = 0; sts_o7_sensorData.over_stay_duration = 0; sts_o7_sensorData.unconscious_duration = 0; sts_o7_sensorData.no_movement_duration = 0; sts_o7_sensorData.unconscious_state = 0; STS_SENSOR_Power_ON(0); STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(); //STS_PRESENCE_SENSOR_TOF_Init(); //HAL_Delay(2000); //STS_PRESENCE_SENSOR_Distance_Measure_Process(); mems_int1_detected=0; } void STS_PRESENCE_SENSOR_TOF_Init(void) { APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS TOF Initializing \r\n"); } void STS_PRESENCE_SENSOR_REEDSWITCH_HALL_Init(void) { APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) REED SWITCH HALL ELEMENT Initializing \r\n"); } void STS_PRESENCE_SENSOR_RSS_Init(void) { APP_LOG(TS_ON, VLEVEL_H, "##### YunHorn SmarToilets(r) MEMS RSS Initializing \r\n"); STS_SENSOR_Power_ON(0); if ((sts_distance_rss_distance==0)&&(sts_sensor_install_height==0)) { uint8_t exit_status =0; exit_status=sts_distance_rss_detector_distance(); if (exit_status ==0) { APP_LOG(TS_ON, VLEVEL_M, "##### RSS Installation Height =%u \r\n", (uint16_t)sts_distance_rss_distance); } else { APP_LOG(TS_ON, VLEVEL_M, "##### RSS Installation Height Error \r\n"); } sts_sensor_install_height=sts_distance_rss_distance; } STS_PRESENCE_SENSOR_NVM_CFG(); sts_rss_config_updated_flag = STS_RSS_CONFIG_DEFAULT; mems_int1_detected=0; } #ifdef STS_M7 void STS_PRESENCE_SENSOR_Get_Event_Status(STS_PRESENCE_SENSOR_Event_Status_t *Status) { uint8_t int_source=0; SysTime_t mems_event_time; //int_source = ADXL345_GetRegisterValue(ADXL345_REG_INT_SOURCE); if (int_source & 0x10) { mems_event_time = SysTimeGetMcuTime(); Status->WakeUpStatus = 1U; event_start_time = mems_event_time.Seconds; } else { Status->WakeUpStatus =0U; } if (int_source & 0x08) { mems_event_time = SysTimeGetMcuTime(); Status->SleepStatus = 1U; event_stop_time = mems_event_time.Seconds; } else { Status->SleepStatus = 0U; } } #endif void STS_PRESENCE_SENSOR_Distance_Measure_Process(void) { uint8_t exit_status = EXIT_SUCCESS, i=0; APP_LOG(TS_OFF, VLEVEL_L, "\r\n ****start_m=%u length_m=%u profile=%u hwaas=%u \r\n", (unsigned int)(distance_cfg.start_m*1000),(unsigned int)(distance_cfg.length_m*1000), (unsigned int)(distance_cfg.acc_profile),(unsigned int)(distance_cfg.hwaas)); do { exit_status = sts_distance_rss_detector_distance(); HAL_Delay(100); i++; } while ((exit_status == EXIT_FAILURE) && (i < 2)); } void STS_PRESENCE_SENSOR_Function_Test_Process(uint8_t *self_test_result, uint8_t count) { uint8_t bring_up_result[20]; STS_SENSOR_Power_ON(0); HAL_Init(); MX_GPIO_Init(); HAL_Delay(150); //wait for sensor ready for (uint8_t i=0;i < count; i++) //while(1) { STS_Lamp_Bar_Self_Test_Simple(); sts_lamp_bar_color = STS_PINK; STS_Lamp_Bar_Refresh(); HAL_Delay(1000); sts_presence_rss_bring_up_test(bring_up_result); HAL_Delay(1000); STS_PRESENCE_SENSOR_Distance_Measure_Process(); } HAL_Delay(1000); memcpy(self_test_result, bring_up_result, 10); mems_int1_detected=0; } uint8_t STS_SENSOR_MEMS_Get_ID(uint8_t *devID) { uint8_t scanned_id[2] = {0x0,0x0}; #if defined(STS_O7)||defined(STS_O6) if (hal_test_spi_read_chipid(scanned_id)) { devID[0] = scanned_id[0]; devID[1] = scanned_id[1]; APP_LOG(TS_OFF, VLEVEL_H,"\r\n--------------devID = %02x %02x \r\n",devID[0], devID[1]); return true; } else { return false; } #endif } void STS_SENSOR_Power_ON(uint8_t cnt) { switch (cnt) { case 0: case 1: case 2: PME_ON; break; default: break; } } void STS_SENSOR_Power_OFF(uint8_t cnt) { switch (cnt) { case 0: case 1: case 2: PME_OFF; break; default: break; } } void STS_SENSOR_MEMS_Reset(uint8_t cnt) { switch (cnt) { case 0: case 1: case 2: HAL_GPIO_TogglePin(MEMS_POWER_GPIO_Port, MEMS_POWER_Pin); break; default: break; } } #ifdef STS_R4 void YUNHORN_STS_R4_SENSOR_Read(STS_R0_SensorDataTypeDef *r4_data) { #ifdef SOAP_LEVEL_SENSOR r4_data->on_off_event = (sts_soap_level_state==0x0)? 1:0; r4_data->measure_tech = 0x0; // capacity measure #endif sensor_data_ready = 0x1; } void YUNHORN_STS_R4_SENSOR_Init(void) { r4_data.on_off_event = 0x0; r4_data.measure_tech = 0x0; sensor_data_ready = 0x0; } #endif #if defined(YUNHORN_STS_R4_ENABLED) void STS_R0_SENSOR_Read(STS_R0_SensorDataTypeDef *r0_data) { #ifdef SOAP_LEVEL_SENSOR r0_data->on_off_event = sts_soap_level_state; r0_data->measure_tech = 0; /* 0: capacit, 1:dTof, 2: ultrasonic */ #elif defined(TOF_1)||defined(TOF_2)||defined(TOF_3) r0_data->measure_tech = 1; /* 0: capacit, 1:dTof, 2: ultrasonic */ r0_data->distance_mm = sts_tof_distance_data[0]; r0_data->distance1_mm = sts_tof_distance_data[1]; r0_data->distance2_mm = sts_tof_distance_data[2]; #elif defined(ROCTEC_R5) r0_data->distance1_mm = sts_tof_distance_data[0]+sts_tof_distance_data[1]+sts_tof_distance_data[2]; #endif sensor_data_ready = 1; } #endif void STS_SENSOR_NVM_CFG(void) { } void STS_SENSOR_NVM_CFG_SIMPLE(void) { } #if defined(YUNHORN_STS_O5_ENABLED) void STS_O5_SENSOR_Read(STS_OO_SensorDataTypeDef *oo_data) { oo_data->state_sensor1_on_off = sts_reed_hall_result; sensor_data_ready = 1; } #endif /* reedswitch 1 on off */ void OnSensor1StateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); if (sts_hall1_read == STS_Status_Door_Close) { sts_o7_sensorData.event_sensor1_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor1_duration = 0; APP_LOG(TS_OFF, VLEVEL_L, "Door Closed ---Timer start: %u\r\n",sts_o7_sensorData.event_sensor1_start_time ); } else if (sts_hall1_read==STS_Status_Door_Open) { sts_o7_sensorData.event_sensor1_start_time = 0; sts_o7_sensorData.event_sensor1_stop_time = sensor_event_time.Seconds; //sts_o7_sensorData.event_sensor1_duration = 0; } } /* SOS emergency button on off */ void OnSensor2StateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); if (sts_hall2_read==STS_Status_SOS_Pushdown) { sts_o7_sensorData.event_sensor2_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor2_duration = 0; }else if (sts_hall2_read==STS_Status_SOS_Release) { sts_o7_sensorData.event_sensor2_start_time =0; sts_o7_sensorData.event_sensor2_stop_time = sensor_event_time.Seconds; //sts_o7_sensorData.event_sensor2_duration = 0; } } /* motion sensor RSS ON-OFF */ void OnSensor3StateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); #if 0 if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter { return ; } #endif if (sts_rss_result == STS_RESULT_MOTION) { sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_motion_duration = 0; } else if (sts_rss_result == STS_RESULT_NO_MOTION) { sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds; //sts_o7_sensorData.event_sensor3_motion_duration = 0; } last_sts_rss_time_stamp = sensor_event_time.Seconds; } /* motion sensor A: Motion/No-Motion Detection, Unconscious Detection */ void OnSensor3AStateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); #if 0 if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter { return ; } #endif if (sts_rss_result == STS_RESULT_MOTION) { sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_motion_duration = 0; } else if (sts_rss_result == STS_RESULT_NO_MOTION) { sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds; //sts_o7_sensorData.event_sensor3_motion_duration = 0; } last_sts_rss_time_stamp = sensor_event_time.Seconds; } /* motion sensor B, Fall Detection suggestionF */ void OnSensor3BStateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); #if 0 if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter { return ; } #endif switch (sts_fall_rising_detected_result) { case STS_PRESENCE_NORMAL: sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds; break; case STS_PRESENCE_FALL: if (motion_in_hs_zone[0][motion_detected_count]) { sts_o7_sensorData.event_sensor3_fall_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_fall_duration = 0; } break; case STS_PRESENCE_RISING: break; case STS_PRESENCE_LAYDOWN: break; case STS_PRESENCE_STAYSTILL: case STS_PRESENCE_NO_MOVEMENT: case STS_PRESENCE_UNCONSCIOUS: sts_o7_sensorData.event_sensor3_no_movement_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_unconcious_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_unconcious_duration = 0; sts_o7_sensorData.event_sensor3_no_movement_duration = 0; sts_o7_sensorData.fall_laydown_duration = 0; break; default: break; } last_sts_rss_time_stamp = sensor_event_time.Seconds; } /* motion sensor C: Over stay detection */ void OnSensor3CStateChanged(void) { SysTime_t sensor_event_time = SysTimeGetMcuTime(); #if 0 if ((sensor_event_time.Seconds - last_sts_rss_time_stamp) < 3 ) //less than 3 seconds ... return for flipping filter { return ; } #endif if (sts_rss_result == STS_RESULT_MOTION) { sts_o7_sensorData.event_sensor3_motion_start_time = sensor_event_time.Seconds; sts_o7_sensorData.event_sensor3_motion_duration = 0; } else if (sts_rss_result == STS_RESULT_NO_MOTION) { sts_o7_sensorData.event_sensor3_motion_stop_time = sensor_event_time.Seconds; //sts_o7_sensorData.event_sensor3_motion_duration = 0; } last_sts_rss_time_stamp = sensor_event_time.Seconds; } void OnSensor4StateChanged(void) { #if 0 SysTime_t sensor_event_time = SysTimeGetMcuTime(); // reserved... to be finalized 2024-06-03 if (sts_xxx_result) sts_o7_sensorData.event_sensor4_start_time = sensor_event_time.Seconds; else sts_o7_sensorData.event_sensor4_stop_time = sensor_event_time.Seconds; #endif } /* USER CODE BEGIN EF */ /* USER CODE END EF */ /* Private Functions Definition -----------------------------------------------*/ /* USER CODE BEGIN PrFD */ /* USER CODE END PrFD */