539 lines
14 KiB
C
539 lines
14 KiB
C
#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;
|
||
} |