Job_SignsPads/STM32/Code/STM32F405/Application/opm.c

539 lines
14 KiB
C
Raw Normal View History

2025-04-22 02:29:37 +00:00
#include "main.h"
#include "math.h"
#include "drv_SGM58031.h"
/*
* opm.c
*
* Created on: 2021624
* 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;
}