Job_SignsPads/STM32/Code/STM32F405/Application/opm.c
2025-04-22 10:29:37 +08:00

539 lines
14 KiB
C
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#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;
}