#include "main.h" #include "math.h" #include "drv_SGM58031.h" /* * opm.c * * Created on: 2021年6月24日 * Author: Eric.wang */ float cal_1310 = 0.0f; float dbm_value_1310 = -50.0f; float Calculate_1310_dbm_array[50] = {0}; float ADC_1310 = 0.0f; char Heart_rate = 0; // 心率 char respiratory_value = 0; // 呼吸值 char body_movement_value = 0; // 体动值 0_正常 3_轻微体动 4_中度体动 5_大幅体动 -100_无效值(一分钟的体动值分布,0x00-oxFF 数值越大,体动越明显) char equipment_status_value = OffBed_Status; // 设备状态值 3_离床 4_在床 5_光纤故障 6_离线 9_传感器负荷 10_信号弱 float test_adc = 0.0f; float test_value = 0.0f; double standard = 0; // 求标准差 uint16_t ads1115_buffer[4]; int channel_1310 = 1; int health_flg = 1; int opticalFibre_flg = 0; int sensorLoad_flg = 0; int lightSignal_flg = 0; float ON_BED_Threshold = -30.0f; float OFF_BED_Threshold = -20.0f; char body_flg = 0; // todo: 增加人体检测标志位 char bodyCheckSignal = BODY_CHECK_ENABLE; // 人体检测标志位 double sum = 0; // 求和 double avgValue = 0; // 求平均数 double last_average = 0; // 求平均数 double var = 0; // 求方差 #define ORGANISMS_EXIST_ENABLE 0 // 非生命体征识别使能 #define ORGANISMS_EXIST_THRESHOLD 0.008f #define ORGANISMS_EXIST_HI_THRESHOLD 0.1f #define ORGANISMS_EXIST_ONCE_COUNT 6 #define ORGANISMS_EXIST_OneSec_COUNT 500 #define ORGANISMS_EXIST_CALCULATION_COUNT 13 char Organisms_OnceFlag = 0; double Organisms_Difference = 0.0f; double Organisms_Difference_CountBuffer[ORGANISMS_EXIST_CALCULATION_COUNT] = {0.0f}; /** * @brief get_optical_power * @param 总体optical判断 * @retval None. */ int StableCount = 0; float maxOpticalPower = -30.0f; extern float SGM58031_ADC_Value; void value_get(float value) { if (value != 0.0f) ADC_1310 = value; else ADC_1310 = SGM58031_ADC_Value; //(SGM58031_ADC_Value + Adjust_ADC(AIN_1310)) / 2; // 两个数据进行融合 可能会更加准一点 if (ADC_1310 < 0.00001f) ADC_1310 = 0.00001f; dbm_value_1310 = 10 * log10(ADC_1310 / pow(10, channel_1310)) + cal_1310; if (channel_1310 == 0x01) { dbm_value_1310 = dbm_value_1310 - 0.7f; } StableCount++; if (dbm_value_1310 > maxOpticalPower && StableCount >= 0x0FFF) { StableCount = 0; maxOpticalPower = dbm_value_1310; } } void get_optical_power(void) { float avgVolt = 0.0f; avgVolt = get_optical_1310_power(); value_get(avgVolt); } void get_ADS1115(void) { } /** * @brief get_optical_1310_power * @param OLT-1490 ADC1-3 * @retval None. */ float volt = 0.0f; float get_optical_1310_power(void) { // char Channel_Flag = 0; uint8_t i = 0, j = 0; float avgValue = 0, tem = 0; float dataBuffer[25] = {0.0}; release_volt(); volt = SGM58031_ReadADCValue(); if ((volt > MAX_VOLT) && (channel_1310 > ADG704_L)) // 电压太高 { // 切换放大倍数更小的通道 channel_1310--; } else if ((volt < MIN_VOLT) && (channel_1310 < ADG704_H)) // 电压太低 { // 切换放大倍数更大的通道 channel_1310++; } set_1310_channel(channel_1310); // 切换通道 release_volt(); // 切换通道,so 保持电容放电 for (i = 0; i < 25; i++) /*sample for 25 */ { dataBuffer[i] = SGM58031_ReadADCValue(); // 获取电压值 delay_ms(2); } for (j = 0; j < 25 - 1; j++) /*array with data big up */ { for (i = 1; i < 25 - j; i++) { if (dataBuffer[i] < dataBuffer[i - 1]) { tem = dataBuffer[i]; dataBuffer[i] = dataBuffer[i - 1]; dataBuffer[i - 1] = tem; } } } for (i = 5; i < 20; i++) { avgValue = avgValue + dataBuffer[i]; } volt = avgValue / 15.00f; return volt; } void set_1310_channel(uint8_t ch) { switch (ch) { case 0: { OP1_B = 0; OP1_A = 0; } break; case 1: { OP1_B = 0; OP1_A = 1; } break; case 2: { OP1_B = 1; OP1_A = 0; } break; case 3: { OP1_B = 1; OP1_A = 1; } break; default: break; } } /** * @brief release_volt * @param 保持电容放电 * @retval None. */ void release_volt(void) { // Dis_1310 = 1; // delay_ms(5); Dis_1310 = 0; // delay_ms(5); } char Organisms_CountDoneFlag = 0; extern uint8_t g_mon, g_day, g_hour, g_min, g_sec; void get_check_result(void) { // "health": 1, // 1:健康; -1:不健康 // "status": // 1:正常; 0:离线; -1:故障 // { // "opticalFibre": 0, // 光纤 // "sensorLoad": 0, // 传感器负荷 // "lightSignal": 0 // 光信号 // } #if ORGANISMS_EXIST_ENABLE // 白天进行非生命识别 static char Dif_Count = 0; static char Count_Flag = 0; static char InBed_Count = 0; static char OffBed_Count = 0; double Organisms_Difference_Old = 0.0f; double Organisms_Difference_Dif = 0.0f; static double CheckBed_sum = 0; // 求和 static double CheckBed_standard = 0; // 求差 static double CheckBed_average = 0; // 求平均数 static double CheckBed_last_average = 0; // 求平均数 if (bodyCheckSignal == BODY_CHECK_ENABLE) { CheckBed_sum = 0; for (int i = 0; i <= model_num; i++) { CheckBed_sum += ppg_data_500_buf[i]; // 求和 } CheckBed_average = CheckBed_sum / model_num; // 求平均值 CheckBed_standard = fabs(fabs(CheckBed_average) - fabs(CheckBed_last_average)) * 100; CheckBed_last_average = CheckBed_average; if (Organisms_Difference != Organisms_Difference_Old && Organisms_OnceFlag && !Organisms_CountDoneFlag) { Organisms_OnceFlag = 0; Organisms_Difference_Dif = Organisms_Difference_Old - Organisms_Difference; Organisms_Difference_Old = Organisms_Difference; Organisms_Difference_CountBuffer[Dif_Count] = Organisms_Difference_Dif; Dif_Count++; if (Dif_Count >= ORGANISMS_EXIST_CALCULATION_COUNT && !Count_Flag) { Dif_Count = 0; Count_Flag = 1; InBed_Count = 0; OffBed_Count = 0; for (char i = 0; i < ORGANISMS_EXIST_CALCULATION_COUNT; i++) { if (fabs(Organisms_Difference_CountBuffer[i]) >= ORGANISMS_EXIST_THRESHOLD) { InBed_Count++; } else { OffBed_Count++; } } Organisms_CountDoneFlag = 1; } else if (Count_Flag) { if (Dif_Count >= ORGANISMS_EXIST_CALCULATION_COUNT) { Dif_Count = 0; } InBed_Count = 0; OffBed_Count = 0; for (char i = 0; i < ORGANISMS_EXIST_CALCULATION_COUNT; i++) { if (fabs(Organisms_Difference_CountBuffer[i]) >= ORGANISMS_EXIST_HI_THRESHOLD) { InBed_Count = 0; OffBed_Count = 0; break; } if (fabs(Organisms_Difference_CountBuffer[i]) >= ORGANISMS_EXIST_THRESHOLD) { InBed_Count++; } else if (fabs(Organisms_Difference_CountBuffer[i]) < ORGANISMS_EXIST_THRESHOLD) { OffBed_Count++; } } } } } else { InBed_Count = 0; OffBed_Count = 0; } #endif if (dbm_value_1310 < FAULT_OPM) // 光纤故障 { equipment_status_value = Fiber_Error_Status; opticalFibre_flg = -1; // 光纤 sensorLoad_flg = 1; // 传感器 lightSignal_flg = 1; // 光信号 health_flg = -1; // 1:健康; -1:不健康 } else if (dbm_value_1310 <= WEAK_OPM) // 信号弱 { equipment_status_value = WeakSignal_Status; opticalFibre_flg = 1; // 光纤 sensorLoad_flg = 1; // 传感器 lightSignal_flg = -1; // 光信号 health_flg = -1; // 1:健康; -1:不健康 } else if (dbm_value_1310 >= 0) // 传感器负荷 { equipment_status_value = Sensor_Load_Status; opticalFibre_flg = 1; // 光纤 sensorLoad_flg = -1; // 传感器 lightSignal_flg = 1; // 光信号 health_flg = -1; // 1:健康; -1:不健康 } #if 0 else if (dbm_value_1310 >= OFF_BED_Threshold) // 离床-18.5 { equipment_status_value = OffBed_Status; opticalFibre_flg = 0; // 光纤 sensorLoad_flg = 0; // 传感器 lightSignal_flg = 0; // 光信号 health_flg = 1; // 1:健康; -1:不健康 #if NOT_PRE_STAGE OffBed_Flag = 0; // 离床 #endif #if ORGANISMS_EXIST_ENABLE if (bodyCheckSignal == BODY_CHECK_ENABLE) { Dif_Count = 0; Count_Flag = 0; InBed_Count = 0; OffBed_Count = 0; Organisms_CountDoneFlag = 0; } #endif } #if ORGANISMS_EXIST_ENABLE else if ((dbm_value_1310 > ON_BED_Threshold) && (dbm_value_1310 < OFF_BED_Threshold) && (InBed_Count >= OffBed_Count)) // 有重物,是人体 #else else if ((dbm_value_1310 > ON_BED_Threshold) && (dbm_value_1310 < OFF_BED_Threshold)) // 有重物 #endif { equipment_status_value = InBed_Status; OffBed_Flag = 4; // 在床 opticalFibre_flg = 1; // 光纤 sensorLoad_flg = 1; // 传感器 lightSignal_flg = 1; // 光信号 health_flg = 1; // 1:健康; -1:不健康 sum = 0; for (int i = 0; i <= model_num; i++) { sum += ppg_data_500_buf[i]; // 求和 } avgValue = sum / model_num; // 求平均值 standard = (fabs(avgValue - last_average)) * 100; last_average = avgValue; #if ORGANISMS_EXIST_ENABLE if (bodyCheckSignal == BODY_CHECK_ENABLE) { // 在床变离床,有重物情况下若有体动则重新进行判断 if (CheckBed_standard > Huge_Movement_Threshold) { Dif_Count = 0; Count_Flag = 0; InBed_Count = 0; OffBed_Count = 0; Organisms_CountDoneFlag = 0; } } #endif } #if ORGANISMS_EXIST_ENABLE else if ((dbm_value_1310 > ON_BED_Threshold) && (dbm_value_1310 < OFF_BED_Threshold) && (InBed_Count < OffBed_Count)) // 有重物,都是不是人体 { if (bodyCheckSignal == BODY_CHECK_ENABLE) { equipment_status_value = OffBed_Status; opticalFibre_flg = 0; // 光纤 sensorLoad_flg = 0; // 传感器 lightSignal_flg = 0; // 光信号 health_flg = 1; // 1:健康; -1:不健康 // TODO:此处需要详细解析,有重物情况下若有体动则重新进行判断 if (CheckBed_standard > Huge_Movement_Threshold) { Count_Flag = 0; InBed_Count = 0; OffBed_Count = 0; Organisms_CountDoneFlag = 0; } } } #endif #endif } int Organisms_SurviveCount = -1; void get_opm_number(void) { uint8_t farray[4] = {0}; static char CountNumber = 0; static float Organisms_Survive_StandardDeviation[3] = {0.0f}; // 生物体存活标准差 static float Organisms_Survive_Buffer[ORGANISMS_EXIST_OneSec_COUNT] = {0.0f}; // 生物体存活缓存 value_get(0.0f); // ppg_data2_buf[wifi_len] = dbm_value_1310; ppg_data_500_buf[wifi_len_500] = dbm_value_1310; // BH_data_500[wifi_len_500] = (unsigned short int)(abs((int)(dbm_value_1310 * 1000))); BH_data_500[wifi_len_500] = (unsigned short int)((int)(ADC_1310 * 10000)); Calculate_1310_dbm_array[CountNumber] = dbm_value_1310; stage_len++; CountNumber++; if (CountNumber >= 50) CountNumber = 0; if (stage_len >= 50) { stage_len = 0; ppg_stage_buf[ppg_stage_index] = BH_data_500[wifi_len_500]; if (BH_data_500[wifi_len_500] > max_min2[0]) // 最大值 max_min2[0] = BH_data_500[wifi_len_500]; if (BH_data_500[wifi_len_500] < max_min2[1]) // 最小值 max_min2[1] = BH_data_500[wifi_len_500]; ppg_stage_index++; if (ppg_stage_index >= 10) { // printf("t max:%d t min:%d \n",max_min2[0],max_min2[1]); ppg_stage_index = 0; // InsertQueue(Stage_q, (unsigned short int *)ppg_stage_buf, 10, (unsigned short int *)max_min2); max_min2[0] = 0; max_min2[1] = 50000; } } if (wifi_len_500 >= model_num) { for (int i = 0; i < model_num; i++) { // wifi_opm_send_buf[17 + 4 * i] = wifi_opm_buf[17 + 4 * i]; // wifi_opm_send_buf[18 + 4 * i] = wifi_opm_buf[18 + 4 * i]; // wifi_opm_send_buf[19 + 4 * i] = wifi_opm_buf[19 + 4 * i]; // wifi_opm_send_buf[20 + 4 * i] = wifi_opm_buf[20 + 4 * i]; } wifi_len_500 = 0; wifi_len_500_flg = 1; #if ORGANISMS_EXIST_ENABLE if (bodyCheckSignal == BODY_CHECK_ENABLE) { Organisms_SurviveCount++; // 生物体检测 Organisms_ExistCheck(Organisms_Survive_Buffer); } #endif } // memcpy(farray, &dbm_value_1310, sizeof(dbm_value_1310)); #if ORGANISMS_EXIST_ENABLE if (bodyCheckSignal == BODY_CHECK_ENABLE) { Organisms_Survive_Buffer[wifi_len_500] = dbm_value_1310; } #endif // wifi_opm_buf[17 + 4 * wifi_len_500] = farray[0]; // wifi_opm_buf[18 + 4 * wifi_len_500] = farray[1]; // wifi_opm_buf[19 + 4 * wifi_len_500] = farray[2]; // wifi_opm_buf[20 + 4 * wifi_len_500] = farray[3]; wifi_len_500++; } double Organisms_Result = 0.0f; double Organisms_ResultSum = 0.0f; // 生物体结果累加值 double Organisms_AllSum = 0.0f; // 生物体总累加值 double Organisms_AllAvg = 0.0f; // 生物体总平均值 float Organisms_SurviveAvg[ORGANISMS_EXIST_ONCE_COUNT] = {0.0f}; // 生物体分平均值 double Organisms_Survive_StandardDeviation[ORGANISMS_EXIST_ONCE_COUNT] = {0.0f}; // 生物体分标准值 double Organisms_OldValue = 0.0f; double Organisms_ExistCheck(float *buf) { double Organisms_SurviveSum = 0.0f; // 生物体分累加值 double OrganismsStandardSum = 0.0f; // 生物体标准差累加值 // 求和 for (int i = 0; i < ORGANISMS_EXIST_OneSec_COUNT; i++) { Organisms_AllSum += buf[i]; Organisms_SurviveSum += buf[i]; } // 作均值 Organisms_SurviveAvg[Organisms_SurviveCount] = Organisms_SurviveSum / ORGANISMS_EXIST_OneSec_COUNT; for (int i = 0; i < ORGANISMS_EXIST_OneSec_COUNT; i++) { OrganismsStandardSum += my_pow((buf[i] - Organisms_SurviveAvg[Organisms_SurviveCount])); } // 求标准差 Organisms_Survive_StandardDeviation[Organisms_SurviveCount] = sqrt(OrganismsStandardSum / ORGANISMS_EXIST_OneSec_COUNT); memset(buf, 0, ORGANISMS_EXIST_OneSec_COUNT); // 计算 ORGANISMS_EXIST_ONCE_COUNT 秒的标准差,合成 if (Organisms_SurviveCount >= ORGANISMS_EXIST_ONCE_COUNT) { Organisms_SurviveCount = -1; Organisms_ResultSum = 0; Organisms_AllAvg = Organisms_AllSum / (ORGANISMS_EXIST_OneSec_COUNT * ORGANISMS_EXIST_ONCE_COUNT); for (int i = 0; i < ORGANISMS_EXIST_ONCE_COUNT; i++) { Organisms_ResultSum += (ORGANISMS_EXIST_OneSec_COUNT * ((my_pow(Organisms_Survive_StandardDeviation[i])) + (my_pow(Organisms_AllAvg - Organisms_SurviveAvg[i])))); } Organisms_Result = sqrt(Organisms_ResultSum / (ORGANISMS_EXIST_OneSec_COUNT * ORGANISMS_EXIST_ONCE_COUNT)); Organisms_Difference = Organisms_Result - Organisms_OldValue; Organisms_OldValue = Organisms_Result; Organisms_AllSum = 0; Organisms_OnceFlag = 1; } return Organisms_Result; } double my_pow(float value) { double result = 0.0f; result = value * value; return result; } /** * @function: * @brief: None * @return {*} * @author: lzc */ void ConvertMoveStd(void) { sum = 0; for (int i = 0; i <= model_num; i++) { sum += ppg_data_500_buf[i]; // 求和 } avgValue = sum / model_num; // 求平均值 standard = (fabs(avgValue - last_average)) * 100; last_average = avgValue; }