1324 lines
41 KiB
C
1324 lines
41 KiB
C
/*
|
||
* @Description:
|
||
* @Version: 1.0
|
||
* @Author: lzc
|
||
* @Date: 2023-12-07 15:08:04
|
||
* @LastEditors: lzc
|
||
* @LastEditTime: 2024-06-25 15:45:34
|
||
*/
|
||
#include "sys.h"
|
||
#include "opm.h"
|
||
#include "usart.h"
|
||
#include "cJSON.h"
|
||
#include "general.h"
|
||
#include "wificom.h"
|
||
#include "sleepReport.h"
|
||
|
||
const char s_Date[12] = __DATE__; // 取编译日期
|
||
const char s_Time[9] = __TIME__; // 取编译时间
|
||
|
||
uint8_t BreathRateWarn = 0;
|
||
uint8_t HeartBeatRateWarn = 0;
|
||
|
||
uint8_t BreathRate = 0;
|
||
uint8_t HeartBeatRate = 0;
|
||
uint8_t BreathRate_Record = 0;
|
||
uint8_t HeartBeatRate_Record = 0;
|
||
|
||
uint64_t reportTimeClock = 0;
|
||
uint64_t keepAliveCount = 0;
|
||
|
||
uint8_t B_AvgValue_Warn = 0;
|
||
uint8_t H_AvgValue_Warn = 0;
|
||
uint8_t M_AvgValue_Warn = 0;
|
||
|
||
static uint16_t Array_Count = 0;
|
||
static uint32_t B_AvgValueSum = 0; // 呼吸一分钟总数
|
||
static uint32_t H_AvgValueSum = 0; // 心跳一分钟总数
|
||
static uint32_t M_AvgValueSum = 0; // 体动一分钟总数
|
||
static uint16_t AvgValueCount = 0;
|
||
static uint64_t TimeClock_OverValueCount = 0;
|
||
|
||
extern float Diff;
|
||
extern uint16_t number0;
|
||
extern char wifi_json_flg;
|
||
extern char FFT_Count_State_Flag;
|
||
extern uint8_t g_mon, g_day, g_hour, g_min, g_sec;
|
||
|
||
extern WarningMsg_t WarningMsg;
|
||
extern warning_config_t warning_config;
|
||
|
||
static int bR_warningCounter[4] = {0};
|
||
static int hR_warningCounter[6] = {0};
|
||
static char BuildTimeString[36] = {0};
|
||
extern char MovementBuffer[REPORT_BUFFER_MAX];
|
||
extern char HeartRateBuffer[REPORT_BUFFER_MAX];
|
||
extern char BreathRateBuffer[REPORT_BUFFER_MAX];
|
||
extern char sleepStatusBuffer[REPORT_BUFFER_MAX];
|
||
extern char sleepTempBuffer[REPORT_BUFFER_MAX];
|
||
|
||
void CheckCoiledData(void);
|
||
void sleepReportLastPack(void);
|
||
void sleepReportClearData(void);
|
||
void bubbleSort(int a[], int n);
|
||
void checkCounters(uint8_t Breath, uint8_t Heart);
|
||
void wifiSendMsgOneMoreTimes(uint8_t *data, uint32_t length, char Times);
|
||
void WarnMsg_CheckStatus(uint8_t breathRate, uint8_t heartbeat, uint8_t Move);
|
||
|
||
uint16_t delateLastAwayBedData(uint16_t Array_Size, char *Buffer);
|
||
/**
|
||
* @function: LED_judge
|
||
* @brief: 判断LED的状态
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void LED_judge(void)
|
||
{
|
||
if (TimeClock_Flag == 1)
|
||
{
|
||
switch (equipment_status_value)
|
||
{
|
||
case 3: // 离床
|
||
LED_B = 1;
|
||
LED_R = 1;
|
||
LED_G = !LED_G;
|
||
break;
|
||
case 4: // 在床
|
||
LED_B = 1;
|
||
LED_R = 1;
|
||
LED_G = 0;
|
||
break;
|
||
default:
|
||
LED_B = 1;
|
||
LED_G = 1;
|
||
LED_R = !LED_R;
|
||
printf("ERROR:LOW OPTION");
|
||
break;
|
||
}
|
||
}
|
||
// note:在睡眠时一直喂狗防止出现问题
|
||
if (Array_Count != 0)
|
||
IWDG_Feed();
|
||
}
|
||
|
||
/**
|
||
* @function: Warn_UpdateTimeTick
|
||
* @brief: 更新时间
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void Warn_UpdateTimeTick(void)
|
||
{
|
||
WarningMsg.Move_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
WarningMsg.Heart_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
WarningMsg.Breath_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
|
||
/**
|
||
* @function: wifi_buf_synthesis
|
||
* @brief 体动以及在离床的数据组包
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
#define REPORT_DEBUG 1 // 是否开启睡眠报告的调试
|
||
#if REPORT_DEBUG
|
||
#define REPORT_OVERTIME 5 // (5分钟以内的在床清除)
|
||
#define MSG_DATA_LENGTH 120 // 数据长度
|
||
#define REPORT_UPLOAD_ONCE 10 // 每隔多久上报一次睡眠报告
|
||
#define OFF_BED_15_MIN_VALUE 1800 // 离床总时间 0.5 Sec / 次 = 1800
|
||
#define OFF_BED_30_MIN_VALUE 3600 // 离床总时间 0.5 Sec / 次 = 3600
|
||
#define OFF_BED_45_MIN_VALUE 5400 // 离床总时间 0.5 Sec / 次 = 5400
|
||
#define OFF_BED_60_MIN_VALUE 7200 // 离床总时间 0.5 Sec / 次 = 3600
|
||
#define ONE_MINUTES_TICK_VALUE 120 // 500ms一次 用于1分钟计时
|
||
#else
|
||
#define REPORT_OVERTIME 10 //(10分钟以内的在床清除)
|
||
#define MSG_DATA_LENGTH (30) // 数据长度
|
||
#define REPORT_UPLOAD_ONCE 30 // 每隔多久上报一次睡眠报告
|
||
#define OFF_BED_30_MIN_VALUE 3600 // 离床总时间 0.5 Sec / 次 = 3600
|
||
#define OFF_BED_45_MIN_VALUE 5400 // 离床总时间 0.5 Sec / 次 = 5400
|
||
#define OFF_BED_60_MIN_VALUE 7200 // 离床总时间 0.5 Sec / 次 = 3600
|
||
#define ONE_MINUTES_TICK_VALUE 120
|
||
#endif
|
||
|
||
#define REPORT_LOG 1 // 是否开启睡眠报告的日志
|
||
|
||
char AwayBedFlag = 0;
|
||
char MinutesTickCount = 0;
|
||
|
||
uint32_t OverTimeCount = 0; // 超时计数
|
||
uint64_t InBedTimeStamp = 0;
|
||
|
||
extern char bodyCheckSignal;
|
||
extern float Local_ON_BED_Threshold;
|
||
extern float Local_OFF_BED_Threshold;
|
||
|
||
char OverTime_Count = 0;
|
||
char OverTime_CheckFlag = 0;
|
||
|
||
// Sort the Count
|
||
int count_br[4] = {0};
|
||
int count_hr[6] = {0};
|
||
void wifi_buf_synthesis(void)
|
||
{
|
||
float Difference = 0.0f; // 差值
|
||
uint8_t B_AvgValue = 0;
|
||
uint8_t H_AvgValue = 0;
|
||
uint8_t M_AvgValue = 0;
|
||
// 离床的时间
|
||
uint16_t BedOffCount = 0;
|
||
// 光功数据
|
||
uint8_t farray[2] = {0};
|
||
uint8_t time_num[8] = {0};
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
sprintf(BuildTimeString, "compile %s %s", s_Date, s_Time);
|
||
// 体征数据
|
||
// NOTE:和上一秒的光功进行比较,如果差值大则有体动数据
|
||
/*
|
||
if (standard < Slight_Movement_Threshold) // 体动值判断
|
||
{
|
||
body_movement_value = Normal_Movement;
|
||
}
|
||
else if (standard < Middle_Movement_Threshold)
|
||
{
|
||
body_movement_value = Slight_Movement;
|
||
}
|
||
else if (standard < Large_Movement_Threshold)
|
||
{
|
||
body_movement_value = Middle_Movement;
|
||
}
|
||
else if ((standard < Huge_Movement_Threshold))
|
||
{
|
||
body_movement_value = Large_Movement;
|
||
}
|
||
else if (standard >= (Huge_Movement_Threshold))
|
||
{
|
||
// 睡眠报告在床情况下,开始记录翻身次数(19:00~第二天8:00)
|
||
if (OffBed_Flag == 4 && (g_hour <= 8 || g_hour >= 19))
|
||
Roll_Over_Count++;
|
||
}
|
||
*/
|
||
// note: 采用CWT的体动标志
|
||
body_movement_value = FFT_Count_State_Flag;
|
||
if (equipment_status_value == InBed_Status)
|
||
{
|
||
number0 = 17;
|
||
if (body_movement_value == FFT_No_breath)
|
||
body_movement_value = FFT_Still_state;
|
||
}
|
||
else
|
||
{
|
||
number0 = 17;
|
||
}
|
||
|
||
memcpy(farray, &number0, sizeof(number0));
|
||
wifi_opm_send_buf[0] = 0xA5;
|
||
wifi_opm_send_buf[1] = 0x5A;
|
||
wifi_opm_send_buf[2] = farray[0];
|
||
wifi_opm_send_buf[3] = farray[1];
|
||
#if THE_VERSION
|
||
wifi_opm_send_buf[4] = 0x01; // 帧类型 0x00 hex 0x01 json
|
||
#else
|
||
wifi_opm_send_buf[4] = 0x00; // 帧类型 0x00 hex 0x01 json
|
||
#endif
|
||
|
||
memcpy(time_num, &timeClockCount_Send, sizeof(timeClockCount_Send));
|
||
wifi_opm_send_buf[5] = time_num[0];
|
||
wifi_opm_send_buf[6] = time_num[1];
|
||
wifi_opm_send_buf[7] = time_num[2];
|
||
wifi_opm_send_buf[8] = time_num[3];
|
||
wifi_opm_send_buf[9] = time_num[4];
|
||
wifi_opm_send_buf[10] = time_num[5];
|
||
wifi_opm_send_buf[11] = time_num[6];
|
||
wifi_opm_send_buf[12] = time_num[7];
|
||
|
||
// keepAliveCount++;
|
||
|
||
// 动态离床阈值调整 (夜间)
|
||
if ((Array_Count > 0))
|
||
{
|
||
#if 1
|
||
// 略微增加一点阈值范围
|
||
if (abs(Local_OFF_BED_Threshold) - abs(maxOpticalPower) >= (float)3.6)
|
||
{
|
||
if (abs(Local_OFF_BED_Threshold) - abs(maxOpticalPower) >= (float)6.0)
|
||
Difference = 0.8;
|
||
else
|
||
Difference = 0.4;
|
||
ON_BED_Threshold = Local_ON_BED_Threshold - Difference;
|
||
OFF_BED_Threshold = Local_OFF_BED_Threshold + Difference;
|
||
}
|
||
else
|
||
#endif
|
||
{
|
||
ON_BED_Threshold = Local_ON_BED_Threshold - (float)0.2;
|
||
OFF_BED_Threshold = Local_OFF_BED_Threshold + (float)0.2;
|
||
}
|
||
// 在睡眠报告开始计算前清除存储的睡眠报告 便于下一次生成
|
||
if (g_hour == NIGHT_SLEEP_POS_2 - 1 && g_min == 30)
|
||
{
|
||
// 清除存储的睡眠报告
|
||
sleepReportClearData();
|
||
}
|
||
}
|
||
else
|
||
{
|
||
ON_BED_Threshold = Local_ON_BED_Threshold;
|
||
OFF_BED_Threshold = Local_OFF_BED_Threshold;
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////// 人体在床
|
||
if (equipment_status_value == InBed_Status)
|
||
{
|
||
wifi_opm_send_buf[13] = HeartBeatRate; // nnom_output_data_BH_KC[1]是预测的心跳值
|
||
wifi_opm_send_buf[14] = BreathRate; // nnom_output_data_BH_KC[0]是预测的呼吸值
|
||
wifi_opm_send_buf[15] = body_movement_value; // 体动值 0_正常 3_轻微体动 4_中度体动 5_大幅体动 -100_无效值(一分钟的体动值分布,0x00-oxFF 数值越大,体动越明显)
|
||
wifi_opm_send_buf[16] = InBed_Status; // 设备状态值 3_离床 4_在床 5_光纤故障 9_传感器负荷 10_信号弱
|
||
|
||
#if THE_VERSION
|
||
if (warning_config.sex != 0)
|
||
{
|
||
BreathRateWarn = BreathRate;
|
||
HeartBeatRateWarn = HeartBeatRate;
|
||
checkCounters(BreathRateWarn, HeartBeatRateWarn);
|
||
WarnMsg_CheckStatus(BreathRateWarn, HeartBeatRateWarn, body_movement_value);
|
||
}
|
||
else
|
||
{
|
||
// printf("Wait Config...\r\n");
|
||
// wifi_crc_send(get_config_buf, 13);
|
||
}
|
||
#else
|
||
;
|
||
#endif
|
||
OverTimeCount = 0;
|
||
// 1分钟记录一次
|
||
if (MinutesTickCount >= ONE_MINUTES_TICK_VALUE)
|
||
{
|
||
B_AvgValue = B_AvgValueSum / AvgValueCount;
|
||
H_AvgValue = H_AvgValueSum / AvgValueCount;
|
||
M_AvgValue = M_AvgValueSum / AvgValueCount;
|
||
// 如果在床算出都是0则给默认值
|
||
if (H_AvgValue == 0 && B_AvgValue == 0)
|
||
{
|
||
H_AvgValue = 68;
|
||
B_AvgValue = 18;
|
||
}
|
||
B_AvgValue_Warn = B_AvgValue;
|
||
H_AvgValue_Warn = H_AvgValue;
|
||
M_AvgValue_Warn = M_AvgValue;
|
||
/*
|
||
if (g_hour > (NIGHT_SLEEP_POS_2 - 1) || g_hour < NIGHT_SLEEP_POS_1)
|
||
{
|
||
#if REPORT_DEBUG
|
||
// 20~8 周期内开始记录
|
||
// printf("\r\n-------------------!!!One Minute Done!!!---------------------\r\n");
|
||
// printf("B_AvgValue :%d \r\n", B_AvgValue);
|
||
// printf("H_AvgValue :%d \r\n", H_AvgValue);
|
||
// printf("M_AvgValue :%d \r\n", M_AvgValue);
|
||
// printf("\r\n------------------------ end ------------------------------\r\n");
|
||
// printf("B_AvgValue %d ,H_AvgValue %d,M_AvgValue %d\r\n", B_AvgValue, H_AvgValue, M_AvgValue);
|
||
// wifi_local_log_send("InBed", B_AvgValue, H_AvgValue, M_AvgValue);
|
||
#else
|
||
printf("[IN] = !!!! B_AvgValue %d ,H_AvgValue %d,M_AvgValue %d,Array_Count %d !!!!\r\n", B_AvgValue, H_AvgValue, M_AvgValue, Array_Count);
|
||
#endif
|
||
bodyCheckSignal = BODY_CHECK_DISABLE; // 表示在床则不进行检测非生命体
|
||
// BreathRateBuffer[Array_Count] = B_AvgValue;
|
||
// HeartRateBuffer[Array_Count] = H_AvgValue;
|
||
// MovementBuffer[Array_Count] = M_AvgValue;
|
||
if (OverTime_Count < REPORT_OVERTIME)
|
||
OverTime_Count++;
|
||
if (Array_Count < REPORT_BUFFER_MAX) // 必须12小时以内否则数组越界,数组定义现在720
|
||
{
|
||
CheckCoiledData();
|
||
// TODO: 连续在床 REPORT_OVERTIME 分钟以上则开始记录
|
||
if (OverTime_Count >= REPORT_OVERTIME)
|
||
{
|
||
if (OverTime_CheckFlag)
|
||
Array_Count++;
|
||
}
|
||
else
|
||
{
|
||
BreathRateBuffer[OverTime_Count] = B_AvgValue;
|
||
HeartRateBuffer[OverTime_Count] = H_AvgValue;
|
||
MovementBuffer[OverTime_Count] = M_AvgValue;
|
||
}
|
||
}
|
||
// 记录在床时间戳 需要回溯
|
||
if (Array_Count >= REPORT_OVERTIME && InBedTimeStamp == 0)
|
||
{
|
||
InBedTimeStamp = timeClockCount - (REPORT_OVERTIME * 60 * 1000);
|
||
// printf("Record!!!!!!!!!!! %lld\r\n", InBedTimeStamp);
|
||
}
|
||
if (Array_Count != 0)
|
||
{
|
||
// DONE: 每 REPORT_UPLOAD_ONCE 分钟上报一次睡眠报告
|
||
if (Array_Count % REPORT_UPLOAD_ONCE == 0)
|
||
{
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
// SleepReportGenerate(timeClockCount_Send, Array_Count, 1);
|
||
}
|
||
}
|
||
}*/
|
||
B_AvgValueSum = 0;
|
||
H_AvgValueSum = 0;
|
||
M_AvgValueSum = 0;
|
||
AvgValueCount = 0;
|
||
MinutesTickCount = 0;
|
||
}
|
||
else
|
||
{
|
||
AvgValueCount++;
|
||
B_AvgValueSum += BreathRate;
|
||
H_AvgValueSum += HeartBeatRate;
|
||
M_AvgValueSum += body_movement_value;
|
||
}
|
||
#if REPORT_DEBUG
|
||
char buffer[512] = {0};
|
||
sprintf(buffer, "InBed Time %d:%d:%d | KeepAlive %.1f minute | OverTimeCount %ld",
|
||
g_hour, g_min, g_sec,
|
||
(float)(((keepAliveCount) / (float)2.0f) / 60), OverTimeCount);
|
||
// 是否开启睡眠报告的调试
|
||
#if REPORT_LOG
|
||
wifi_factorySend();
|
||
wifi_RealTime_log_send(buffer);
|
||
#endif
|
||
// printf("OverTimeCount %d ,Array_Count %d\r\n", OverTimeCount, Array_Count);
|
||
#else
|
||
;
|
||
#endif
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////// 人体离床
|
||
else if (equipment_status_value == OffBed_Status)
|
||
{
|
||
wifi_opm_send_buf[13] = 0; // nnom_output_data_BH_KC[1]是预测的心跳值
|
||
wifi_opm_send_buf[14] = 0; // nnom_output_data_BH_KC[0]是预测的呼吸值
|
||
wifi_opm_send_buf[15] = 0; // 体动值 0_正常 3_轻微体动 4_中度体动 5_大幅体动 -100_无效值(一分钟的体动值分布,0x00-oxFF 数值越大,体动越明显)
|
||
wifi_opm_send_buf[16] = equipment_status_value; // 设备状态值 3_离床 4_在床 5_光纤故障 6_离线 9_传感器负荷 10_信号弱
|
||
memset(fft_HeartBeatRate_StashBuffer, 0, sizeof(fft_HeartBeatRate_StashBuffer));
|
||
#if THE_VERSION
|
||
if (warning_config.sex != 0)
|
||
{
|
||
Warn_UpdateTimeTick();
|
||
}
|
||
else
|
||
{
|
||
// printf("Wait Config...\r\n");
|
||
// wifi_crc_send(get_config_buf, 13);
|
||
}
|
||
#else
|
||
;
|
||
#endif
|
||
#if REPORT_DEBUG
|
||
char buffer[512] = {0};
|
||
sprintf(buffer, "OffBed Time %d:%d:%d | KeepAlive %.1f minute | OverTimeCount %ld",
|
||
g_hour, g_min, g_sec,
|
||
(float)(((keepAliveCount) / (float)2.0f) / 60), OverTimeCount);
|
||
// 是否开启睡眠报告的调试
|
||
#if REPORT_LOG
|
||
wifi_factorySend();
|
||
wifi_RealTime_log_send(buffer);
|
||
#endif
|
||
// printf("AwayBed Sum Time OverTimeCount %d ,Array_Count %d\r\n", OverTimeCount, Array_Count);
|
||
#else
|
||
;
|
||
#endif
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
// 1分钟记录一次 离床
|
||
if (MinutesTickCount >= ONE_MINUTES_TICK_VALUE)
|
||
{
|
||
if (OverTime_Count < REPORT_OVERTIME && OverTime_Count > 0)
|
||
OverTime_Count++;
|
||
CheckCoiledData();
|
||
if (Array_Count != 0)
|
||
{
|
||
// 20~8 周期内开始记录离床
|
||
if (g_hour > (NIGHT_SLEEP_POS_2 - 1) || g_hour < (NIGHT_SLEEP_POS_1))
|
||
{
|
||
#if REPORT_DEBUG
|
||
// printf("\r\n-------------------!!!One Minute Done!!!---------------------\r\n");
|
||
// printf("B_AvgValue :0 \r\n");
|
||
// printf("H_AvgValue :0 \r\n");
|
||
// printf("M_AvgValue :0 \r\n");
|
||
// printf("\r\n-------------------------- end ------------------------------\r\n");
|
||
// wifi_local_log_send("OffBed", B_AvgValue, H_AvgValue, M_AvgValue);
|
||
#else
|
||
printf("[OUT] = !!!! B_AvgValue %d,H_AvgValue %d,M_AvgValue %d !!!!!\r\n", B_AvgValue, H_AvgValue, M_AvgValue);
|
||
#endif
|
||
if (Array_Count < REPORT_BUFFER_MAX) // 必须12小时以内否则数组越界,数组定义现在1440
|
||
{
|
||
if (OverTime_CheckFlag)
|
||
Array_Count++;
|
||
}
|
||
// DONE: 每 REPORT_UPLOAD_ONCE 分钟上报一次睡眠报告
|
||
if ((Array_Count % REPORT_UPLOAD_ONCE == 0))
|
||
{
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
|
||
// NOTE:测试版本去除睡眠报告
|
||
// SleepReportGenerate(timeClockCount_Send, Array_Count, 1);
|
||
}
|
||
}
|
||
}
|
||
MinutesTickCount = 0;
|
||
}
|
||
BedOffCount = OFF_BED_30_MIN_VALUE;
|
||
// 离床持续 X 分钟 - 0.5s/次
|
||
if (OverTimeCount >= BedOffCount)
|
||
{
|
||
OverTimeCount = 0;
|
||
// 有一定的记录数(分钟)
|
||
if (Array_Count > MSG_DATA_LENGTH)
|
||
{
|
||
// 并且大于上午5点 小于12点才会清除
|
||
if (g_hour >= 5 && g_hour <= (NIGHT_SLEEP_POS_1))
|
||
sleepReportLastPack();
|
||
// -------------------------conty 20230720 并且大于上午20点 小于23点才会清除---------------------
|
||
if (g_hour >= 20 && g_hour <= 23)
|
||
sleepReportLastPack();
|
||
// ----------------------------------------------------------------------------------------------
|
||
}
|
||
}
|
||
}
|
||
///////////////////////////////////////////////////////////////////////////////////////// 错误情况
|
||
else
|
||
{
|
||
wifi_opm_send_buf[13] = HeartBeatRateWarn; // nnom_output_data_BH_KC[1]是预测的心跳值
|
||
wifi_opm_send_buf[14] = BreathRateWarn; // nnom_output_data_BH_KC[0]是预测的呼吸值
|
||
wifi_opm_send_buf[15] = 0; // 体动值 0_正常 3_轻微体动 4_中度体动 5_大幅体动 -100_无效值(一分钟的体动值分布,0x00-oxFF 数值越大,体动越明显)
|
||
wifi_opm_send_buf[16] = equipment_status_value; // 设备状态值 3_离床 4_在床 5_光纤故障 6_离线 9_传感器负荷 10_信号弱
|
||
#if THE_VERSION
|
||
if (warning_config.sex != 0)
|
||
{
|
||
Warn_UpdateTimeTick();
|
||
}
|
||
else
|
||
{
|
||
// printf("Wait Config...\r\n");
|
||
// wifi_crc_send(get_config_buf, 13);
|
||
}
|
||
#else
|
||
;
|
||
#endif
|
||
#if REPORT_DEBUG
|
||
char buffer[512] = {0};
|
||
sprintf(buffer, "OffBed Time %d:%d:%d | KeepAlive %.1f minute | OverTimeCount %ld",
|
||
g_hour, g_min, g_sec,
|
||
(float)(((keepAliveCount) / (float)2.0f) / 60), OverTimeCount);
|
||
// 是否开启睡眠报告的调试
|
||
#if REPORT_LOG
|
||
wifi_RealTime_log_send(buffer);
|
||
#endif
|
||
// printf("AwayBed Sum Time OverTimeCount %d ,Array_Count %d\r\n", OverTimeCount, Array_Count);
|
||
#else
|
||
;
|
||
#endif
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function: wifi_send
|
||
* @brief: WIFI_的发送
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
// 数据变化上报机制
|
||
// static char Storage_BreathRate = 10;
|
||
// static char Storage_HeartBeatRate = 10;
|
||
// static char Storage_body_movement_value = 0;
|
||
// static char Storage_equipment_status_value = 0;
|
||
|
||
char DataCount = 0;
|
||
char PowerON_Report_Aborted = 0;
|
||
void wifi_send(void)
|
||
{
|
||
uint8_t *ptr = NULL;
|
||
get_check_result();
|
||
// 放弃初次上电的上报的2次体动信息
|
||
if (PowerON_Report_Aborted >= 2)
|
||
{
|
||
wifi_buf_synthesis();
|
||
PowerON_Report_Aborted = 2;
|
||
}
|
||
PowerON_Report_Aborted++;
|
||
if (equipment_status_value == InBed_Status) // 在床
|
||
{
|
||
#if SLEEP_DEBUG_MODE
|
||
#else
|
||
// 数据变化上报机制
|
||
// if (Storage_BreathRate != wifi_opm_send_buf[14] ||
|
||
// Storage_HeartBeatRate != wifi_opm_send_buf[13] ||
|
||
// Storage_body_movement_value != wifi_opm_send_buf[15] ||
|
||
// Storage_equipment_status_value != wifi_opm_send_buf[16])
|
||
// {
|
||
// wifiSendMsgOneMoreTimes(wifi_opm_send_buf, number0, 1);
|
||
// }
|
||
// 一直上报
|
||
wifiSendMsgOneMoreTimes(wifi_opm_send_buf, number0, 1);
|
||
|
||
#endif
|
||
|
||
#if OPM_SEND_MODE
|
||
delay_ms(150);
|
||
wifi_opm_send_buf[2] = 0xE1;
|
||
wifi_opm_send_buf[3] = 0x07;
|
||
wifi_opm_send_buf[4] = 0x2D;
|
||
wifi_crc_send(wifi_opm_send_buf, (4 * 500) + 17);
|
||
wifi_opm_send_buf[2] = 0x11;
|
||
wifi_opm_send_buf[3] = 0x00;
|
||
wifi_opm_send_buf[4] = 0x01;
|
||
delay_ms(150);
|
||
wifi_json_send();
|
||
delay_ms(150);
|
||
#else
|
||
;
|
||
#endif
|
||
OffBed_Time = 0;
|
||
DataCount = 3;
|
||
}
|
||
// 离床定时上报
|
||
else
|
||
{
|
||
#if SLEEP_DEBUG_MODE
|
||
#else
|
||
// // 数据变化上报机制
|
||
// if (Storage_BreathRate != wifi_opm_send_buf[14] ||
|
||
// Storage_HeartBeatRate != wifi_opm_send_buf[13] ||
|
||
// Storage_body_movement_value != wifi_opm_send_buf[15] ||
|
||
// Storage_equipment_status_value != wifi_opm_send_buf[16])
|
||
// {
|
||
// wifiSendMsgOneMoreTimes(wifi_opm_send_buf, number0, 1);
|
||
// }
|
||
// // 一直上报
|
||
wifiSendMsgOneMoreTimes(wifi_opm_send_buf, number0, 1);
|
||
#endif
|
||
}
|
||
wifi_json_flg = 1;
|
||
USART_RX_Length = 0;
|
||
// 数据变化上报机制
|
||
// Storage_BreathRate = wifi_opm_send_buf[14]; // nnom_output_data_BH_KC[0]是预测的呼吸值
|
||
// Storage_HeartBeatRate = wifi_opm_send_buf[13]; // nnom_output_data_BH_KC[1]是预测的心跳值
|
||
// Storage_body_movement_value = wifi_opm_send_buf[15]; // 体动值 0_正常 3_轻微体动 4_中度体动 5_大幅体动 -100_无效值(一分钟的体动值分布,0x00-oxFF 数值越大,体动越明显)
|
||
// Storage_equipment_status_value = wifi_opm_send_buf[16]; // 设备状态值 3_离床 4_在床 5_光纤故障 9_传感器负荷 10_信号弱
|
||
}
|
||
/**
|
||
* @function:
|
||
* @brief: None
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
static char Heartbeat_Warn_Flag = 0, Breath_Warn_Flag = 0, Move_Warn_Flag = 0;
|
||
void Warn_MsgCreate(uint8_t breathRate, uint8_t heartbeat, uint8_t Move)
|
||
{
|
||
char warningMsgSendBuffer[41] = {0};
|
||
// TODO:Send warning Msg
|
||
// NOTE:帧头
|
||
warningMsgSendBuffer[0] = 0XA5;
|
||
warningMsgSendBuffer[1] = 0X5A;
|
||
// NOTE:帧长
|
||
warningMsgSendBuffer[2] = 41;
|
||
warningMsgSendBuffer[3] = 0X00;
|
||
// note:帧类型
|
||
warningMsgSendBuffer[4] = 0X1B;
|
||
////////////////////////////////////////////////////////////////////////
|
||
// note:心率告警开始时间戳
|
||
memcpy(warningMsgSendBuffer + 5, &WarningMsg.Heart_OverThreshold_TimeStamp, 8);
|
||
// note:心率是否有警告
|
||
warningMsgSendBuffer[13] = Heartbeat_Warn_Flag;
|
||
if (Heartbeat_Warn_Flag)
|
||
{
|
||
Heartbeat_Warn_Flag = 0;
|
||
// 发送之前已经更新
|
||
// WarningMsg.Heart_OverThreshold_TimeStamp = WarningMsg.SysTick_Count;
|
||
}
|
||
// note:心率告警是最大还是最小,以及阈值(大于:1 小于 :2)
|
||
if (heartbeat > warning_config.heart_max_th)
|
||
{
|
||
warningMsgSendBuffer[14] = 1;
|
||
warningMsgSendBuffer[15] = warning_config.heart_max_th;
|
||
}
|
||
// note:心率告警是最大还是最小,以及阈值(大于:1 小于 :2)
|
||
else if (heartbeat < warning_config.heart_min_th)
|
||
{
|
||
warningMsgSendBuffer[14] = 2;
|
||
warningMsgSendBuffer[15] = warning_config.heart_min_th;
|
||
}
|
||
// note:持续时间
|
||
warningMsgSendBuffer[16] = warning_config.heart_keep_th;
|
||
// TODO: 当前心率值
|
||
warningMsgSendBuffer[17] = H_AvgValue_Warn;
|
||
////////////////////////////////////////////////////////////////////////
|
||
// note:呼吸告警开始时间戳
|
||
memcpy(warningMsgSendBuffer + 18, &WarningMsg.Breath_OverThreshold_TimeStamp, 8);
|
||
// note:呼吸是否有警告
|
||
warningMsgSendBuffer[26] = Breath_Warn_Flag;
|
||
if (Breath_Warn_Flag)
|
||
{
|
||
Breath_Warn_Flag = 0;
|
||
// 发送之前已经更新
|
||
// WarningMsg.Breath_OverThreshold_TimeStamp = WarningMsg.SysTick_Count;
|
||
}
|
||
// note:呼吸告警是最大还是最小,以及阈值(大于:1 小于 :2)
|
||
if (breathRate > warning_config.breath_max_th)
|
||
{
|
||
warningMsgSendBuffer[27] = 1;
|
||
warningMsgSendBuffer[28] = warning_config.breath_max_th;
|
||
}
|
||
// note:呼吸告警是最大还是最小,以及阈值(大于:1 小于 :2)
|
||
else if (breathRate < warning_config.breath_min_th)
|
||
{
|
||
warningMsgSendBuffer[27] = 2;
|
||
warningMsgSendBuffer[28] = warning_config.breath_min_th;
|
||
}
|
||
// note:持续时间
|
||
warningMsgSendBuffer[29] = warning_config.breath_keep_th;
|
||
// TODO: 当前呼吸值
|
||
warningMsgSendBuffer[30] = B_AvgValue_Warn;
|
||
////////////////////////////////////////////////////////////////////////
|
||
// note:体动告警开始时间戳
|
||
memcpy(warningMsgSendBuffer + 31, &WarningMsg.Move_OverThreshold_TimeStamp, 8);
|
||
// note:体动是否有警告
|
||
warningMsgSendBuffer[39] = Move_Warn_Flag;
|
||
if (Move_Warn_Flag)
|
||
{
|
||
Move_Warn_Flag = 0;
|
||
// 发送之前已经更新
|
||
// WarningMsg.Move_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
// note:持续时间
|
||
warningMsgSendBuffer[40] = warning_config.breath_keep_th;
|
||
for (char i = 0; i < 41; i++)
|
||
{
|
||
// printf("%x ", warningMsgSendBuffer[i]);
|
||
}
|
||
// 发送 必须真的有预警
|
||
if (B_AvgValue_Warn >= warning_config.breath_max_th ||
|
||
B_AvgValue_Warn <= warning_config.breath_min_th ||
|
||
H_AvgValue_Warn >= warning_config.heart_max_th ||
|
||
H_AvgValue_Warn <= warning_config.heart_min_th)
|
||
{
|
||
wifi_crc_send((uint8_t *)warningMsgSendBuffer, 41);
|
||
}
|
||
}
|
||
/**
|
||
* @function:WarnMsg_CheckStatus
|
||
* @brief: None
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void WarnMsg_CheckStatus(uint8_t breathRate, uint8_t heartbeat, uint8_t Move)
|
||
{
|
||
#if REPORT_DEBUG
|
||
// printf("Warning msg check breath rate %d, heartbeat %d, move %d\n", breathRate, heartbeat, Move);
|
||
#else
|
||
;
|
||
#endif
|
||
// NOTE: 心率异常
|
||
if ((heartbeat <= warning_config.heart_max_th && heartbeat >= warning_config.heart_min_th))
|
||
{
|
||
Heartbeat_Warn_Flag = 0;
|
||
// 范围内无异常则一直更新计数值
|
||
WarningMsg.Heart_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
else
|
||
{
|
||
// printf("[INFO]WarningMsg.SysTick_Count is %lld\n", WarningMsg.SysTick_Count);
|
||
// printf("[INFO]WarningMsg.Heart_OverThreshold_CountTick is %lld\n", WarningMsg.Heart_OverThreshold_CountTick);
|
||
// 超过时间阈值,每个count是500ms
|
||
if ((WarningMsg.SysTick_Count - WarningMsg.Heart_OverThreshold_CountTick) >
|
||
((warning_config.heart_keep_th) * 60 * 2))
|
||
{
|
||
Heartbeat_Warn_Flag = 1;
|
||
// 更新计数值
|
||
WarningMsg.Heart_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
// 计算时间戳
|
||
WarningMsg.Heart_OverThreshold_TimeStamp = timeClockCount - (warning_config.heart_keep_th * 60 * 1000);
|
||
// 需要发送预警
|
||
if (heartbeat > warning_config.heart_max_th)
|
||
{
|
||
// 大于最大值
|
||
// printf("!!!!!!!!!!!!!!!!!!Heart Rate Over Event: > %d keep %d \n",
|
||
// warning_config.heart_max_th, warning_config.heart_keep_th);
|
||
WarningMsg.Heart_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
else
|
||
{
|
||
// 小于最小值
|
||
// printf("!!!!!!!!!!!!!!!!!!Heart Rate Over Event: < %d keep %d \n",
|
||
// warning_config.heart_min_th, warning_config.heart_keep_th);
|
||
WarningMsg.Heart_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
}
|
||
}
|
||
// NOTE:呼吸异常 (TODO)
|
||
if (breathRate <= warning_config.breath_max_th && breathRate >= warning_config.breath_min_th)
|
||
{
|
||
Breath_Warn_Flag = 0;
|
||
// 范围内无异常则一直更新计数值
|
||
WarningMsg.Breath_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
else
|
||
{
|
||
// printf("[INFO]WarningMsg.SysTick_Count is %lld\n", WarningMsg.SysTick_Count);
|
||
// printf("[INFO]WarningMsg.Breath_OverThreshold_CountTick is %lld\n", WarningMsg.Breath_OverThreshold_CountTick);
|
||
// 超过时间阈值,每个count是500ms
|
||
if ((WarningMsg.SysTick_Count - WarningMsg.Breath_OverThreshold_CountTick) >
|
||
((warning_config.breath_keep_th) * 60 * 2))
|
||
{
|
||
Breath_Warn_Flag = 1;
|
||
// 更新计数值
|
||
WarningMsg.Breath_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
// 计算时间戳
|
||
WarningMsg.Breath_OverThreshold_TimeStamp = timeClockCount - (warning_config.breath_keep_th * 60 * 1000);
|
||
// 需要发送预警
|
||
if (breathRate > warning_config.breath_max_th)
|
||
{
|
||
// 大于最大值
|
||
// printf("!!!!!!!!!!!!!!!!!!Breath Rate Over Event: > %d keep %d \n",
|
||
// warning_config.breath_max_th, warning_config.breath_keep_th);
|
||
WarningMsg.Breath_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
else
|
||
{
|
||
// 小于最小值
|
||
// printf("!!!!!!!!!!!!!!!!!!Breath Rate Over Event: < %d keep %d \n",
|
||
// warning_config.breath_min_th, warning_config.breath_keep_th);
|
||
WarningMsg.Breath_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
}
|
||
}
|
||
}
|
||
// NOTE:无体动异常
|
||
if (Move != Normal_Movement)
|
||
{
|
||
Move_Warn_Flag = 0;
|
||
// 范围内无异常则一直更新计数值
|
||
WarningMsg.Move_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
// 记录当前时间戳
|
||
WarningMsg.Move_OverThreshold_TimeStamp = timeClockCount;
|
||
}
|
||
else
|
||
{
|
||
warning_config.Move_keep_th = 120; // 默认 120 分钟
|
||
// printf("[INFO]WarningMsg.SysTick_Count is %lld\n", WarningMsg.SysTick_Count);
|
||
// printf("[INFO]WarningMsg.Move_OverThreshold_CountTick is %lld\n", WarningMsg.Move_OverThreshold_CountTick);
|
||
// 超过时间阈值,每个count是500ms
|
||
if ((WarningMsg.SysTick_Count - WarningMsg.Move_OverThreshold_CountTick) >
|
||
((warning_config.Move_keep_th) * 60 * 2))
|
||
{
|
||
Move_Warn_Flag = 1;
|
||
// 计算时间戳
|
||
WarningMsg.Move_OverThreshold_TimeStamp = timeClockCount - (warning_config.Move_keep_th * 60 * 1000);
|
||
// 更新计数值
|
||
WarningMsg.Move_OverThreshold_CountTick = WarningMsg.SysTick_Count;
|
||
// 需要发送预警
|
||
// printf("!!!!!!!!!!!!!!!!!!Move Over Event keep %d \n", warning_config.Move_keep_th);
|
||
}
|
||
}
|
||
if (Move_Warn_Flag || Breath_Warn_Flag || Heartbeat_Warn_Flag)
|
||
{
|
||
Warn_MsgCreate(breathRate, heartbeat, Move);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function:VectorTableReInit
|
||
* @brief: None
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void VectorTableReInit(void)
|
||
{
|
||
if ((*(__IO uint32_t *)0x08008000) == 0x1111) // 1111--升级完成
|
||
{
|
||
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x80000);
|
||
}
|
||
else // 0101--启动老程序
|
||
{
|
||
NVIC_SetVectorTable(NVIC_VectTab_FLASH, 0x10000);
|
||
}
|
||
}
|
||
/**
|
||
* @function: wifi_json_send
|
||
* @brief: json数据的组包
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
static char HealthCount = 0;
|
||
static char StorageHealth = 0;
|
||
static char StorageSensorLoad = 0;
|
||
static char StorageLightSignal = 0;
|
||
static char StorageOpticalFibre = 0;
|
||
void wifi_json_send(void)
|
||
{
|
||
cJSON *cjson_test = NULL;
|
||
cJSON *cjson_status = NULL;
|
||
uint8_t farray[2] = {0};
|
||
char str[512] = {"\0"};
|
||
char JsonOutputBuffer[100] = {0};
|
||
char length = 0;
|
||
// NOTE: 采用组包方式
|
||
sprintf(JsonOutputBuffer, "{\"time\": %llu,\"health\": %d,\"status\":{\"opticalFibre\": %d,\"sensorLoad\": %d,\"lightSignal\": %d}}",
|
||
timeClockCount_Send, health_flg, opticalFibre_flg, sensorLoad_flg, lightSignal_flg);
|
||
// printf("JSON OUTPUT: %s\n", JsonOutputBuffer);
|
||
length = strlen(JsonOutputBuffer);
|
||
str[0] = 0XA5;
|
||
str[1] = 0x5A;
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
str[4] = 0x40;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
#if SLEEP_DEBUG_MODE
|
||
#else
|
||
// // 数据变化上报机制
|
||
// if (StorageHealth != health_flg || StorageSensorLoad != sensorLoad_flg ||
|
||
// StorageLightSignal != lightSignal_flg || StorageOpticalFibre != opticalFibre_flg)
|
||
// {
|
||
// for (char i = 0; i < 3; i++)
|
||
// {
|
||
// USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
// delay_ms(100);
|
||
// }
|
||
// }
|
||
// StorageHealth = health_flg;
|
||
// StorageSensorLoad = sensorLoad_flg;
|
||
// StorageLightSignal = lightSignal_flg;
|
||
// StorageOpticalFibre = opticalFibre_flg;
|
||
// // 定时发送 差不多5秒
|
||
HealthCount++;
|
||
if (HealthCount >= 5)
|
||
{
|
||
HealthCount = 0;
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
}
|
||
#endif
|
||
}
|
||
//-------------------------------------------------------------------------------------------------------------------------------- ADD
|
||
/**
|
||
* @function: wifi_json_send
|
||
* @brief: json数据的组包
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
extern float i_count_Max;
|
||
char ResultBuffer[128] = {0};
|
||
static char factoryStartDeal = 1;
|
||
static char factoryUpload = 0;
|
||
static char factoryCount = 0;
|
||
static char factoryCountValue = 0;
|
||
uint32_t ThirdMinutesCountDown = 0;
|
||
uint16_t OneMinutesCountDown = 0;
|
||
void wifi_factorySend(void)
|
||
{
|
||
#if FACTORY_ENABLE
|
||
cJSON *cjson_test = NULL;
|
||
cJSON *cjson_status = NULL;
|
||
uint8_t farray[2] = {0};
|
||
char str[512] = {"\0"};
|
||
char JsonOutputBuffer[128] = {0};
|
||
char length = 0;
|
||
str[0] = 0XA5;
|
||
str[1] = 0x5A;
|
||
str[4] = 0x2f;
|
||
// NOTE: 采用组包方式
|
||
if (ThirdMinutesCountDown >= (3 * 60 * 2) && factoryStartDeal)
|
||
{
|
||
if (OneMinutesCountDown >= (100 * 2))
|
||
{
|
||
if (factoryCountValue >= 70 && factoryUpload == 0)
|
||
{
|
||
sprintf(JsonOutputBuffer, "{\"累加数据\": %d,\"数据\": %.4f,\"结果\": \"正常\"}",
|
||
factoryCountValue, i_count_Max);
|
||
memcpy(ResultBuffer, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
length = strlen(JsonOutputBuffer);
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
factoryCount++;
|
||
if (factoryCount >= 120)
|
||
factoryUpload = 1;
|
||
factoryStartDeal = 0;
|
||
}
|
||
else if (factoryCountValue < 70 && factoryUpload == 0)
|
||
{
|
||
sprintf(JsonOutputBuffer, "{\"累加数据\": %d,\"数据\": %.4f,\"结果\": \"错误\"}",
|
||
factoryCountValue, i_count_Max);
|
||
memcpy(ResultBuffer, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
length = strlen(JsonOutputBuffer);
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
factoryCount++;
|
||
if (factoryCount >= 120)
|
||
factoryUpload = 1;
|
||
factoryStartDeal = 0;
|
||
}
|
||
OneMinutesCountDown = (100 * 2); // 给默认值
|
||
}
|
||
else
|
||
{
|
||
sprintf(JsonOutputBuffer, "{\"累加数据\": %d,\"数据\": %.4f,\"结果\": \"检测中...\"}",
|
||
factoryCountValue, i_count_Max);
|
||
// 判断是否正常
|
||
if (i_count_Max <= 0.003f)
|
||
factoryCountValue++;
|
||
else if (i_count_Max > 0.003f && factoryCountValue != 0)
|
||
factoryCountValue--;
|
||
length = strlen(JsonOutputBuffer);
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
}
|
||
ThirdMinutesCountDown = (4 * 60 * 2); // 给默认值
|
||
}
|
||
else if (ThirdMinutesCountDown < (3 * 60 * 2))
|
||
{
|
||
sprintf(JsonOutputBuffer, "{\"数据\": %.4f,\"结果\": \"启动...\"}", i_count_Max);
|
||
length = strlen(JsonOutputBuffer);
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
}
|
||
// printf("JSON OUTPUT: %s\n", JsonOutputBuffer);
|
||
// length = strlen(JsonOutputBuffer);
|
||
// str[2] = length & 0xff;
|
||
// str[3] = length >> 8;
|
||
// memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
// // 定时发送 差不多5秒
|
||
// factoryCount++;
|
||
// if (factoryCount >= 2)
|
||
// {
|
||
// factoryCount = 0;
|
||
// USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
// }
|
||
#endif
|
||
}
|
||
//--------------------------------------------------------------------------------------------------------------------------------
|
||
|
||
/**
|
||
* @function: wifi_local_log_send
|
||
* @brief: json数据的组包
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void wifi_local_log_send(char *MyStr, char Breath, char Heart, char Move)
|
||
{
|
||
uint8_t farray[2] = {0};
|
||
char str[1024] = {"\0"};
|
||
char JsonOutputBuffer[512] = {0};
|
||
char length = 0;
|
||
// NOTE: 采用组包方式
|
||
sprintf(JsonOutputBuffer, "{\"addZoneTime\": %llu,\"log\":\"%s\",\"Array_Count\": %d,\"AvgValue\":{\"B_AvgValue\": %d,\"H_AvgValue\": %d,\"M_AvgValue\": %d}}",
|
||
(timeClockCount + (((signed char)warning_config.timeZone) * 60 * 60 * 1000)), MyStr, Array_Count, Breath, Heart, Move);
|
||
length = strlen(JsonOutputBuffer);
|
||
// printf("%d JSON OUTPUT: %s \n", length, JsonOutputBuffer);
|
||
str[0] = 0XA5;
|
||
str[1] = 0x5A;
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
str[4] = 0x2E;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
#if SLEEP_DEBUG_MODE
|
||
#else
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
#endif
|
||
delay_ms(50);
|
||
}
|
||
/**
|
||
* @function: wifi_RealTime_log_send
|
||
* @brief: json数据的组包
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
extern char bootResult;
|
||
extern float Diff;
|
||
extern float FFT_br;
|
||
extern float Diff_Detail;
|
||
extern float ADC_1310;
|
||
extern float i_count_Std;
|
||
extern float i_count_Max;
|
||
extern float OPM_Current;
|
||
extern float OPM_Record;
|
||
extern float OPM_Record_2;
|
||
extern float OPM_Original;
|
||
extern char i_count_off_bed;
|
||
extern char i_count_no_human;
|
||
extern char i_count_No_Breath;
|
||
extern float Diff_detail_Record;
|
||
extern uint16_t EnergyData;
|
||
extern uint16_t FiveMinutesCount;
|
||
extern uint16_t fft_HeartBeatRate_Result;
|
||
extern uint16_t time_HeartBeatRate_Result;
|
||
extern unsigned char version[8];
|
||
extern float stash_Ratio[ARRAY_NUMBER];
|
||
extern float32_t HeartValueRes2Peaks[4];
|
||
extern float Calculate_1310_dbm_array[50];
|
||
void wifi_RealTime_log_send(char *MyStr)
|
||
{
|
||
uint8_t farray[2] = {0};
|
||
char UploadVersion[8] = {0};
|
||
char temp[16] = {0};
|
||
char array[512] = {0};
|
||
char str[3072] = {"\0"};
|
||
char JsonOutputBuffer[3072] = {0};
|
||
int length = 0;
|
||
// NOTE: 采用组包方式
|
||
sprintf(UploadVersion, "%d.%d.%d", version[5], version[6], version[7]);
|
||
// 如果没有存完 就简单出1秒一次的
|
||
if (Calculate_1310_dbm_array[49] == 0x00)
|
||
{
|
||
sprintf(JsonOutputBuffer, "{\"version\":\"%s\",\"build\":\"%s\",\"addZoneTime\": %llu,\"TimeStamp\": %llu,\"bootResult\": %d,\"log\":\"%s\",\"Array_Count\": %d,\"i_count_no\": %d,\"i_count_std\": %f,\"Optical\": %.2f}",
|
||
UploadVersion, BuildTimeString,
|
||
(timeClockCount_Send + (((signed char)warning_config.timeZone) * 60 * 60 * 1000)), timeClockCount_Send, bootResult,
|
||
MyStr, Array_Count, i_count_no_human, (float)i_count_Std, (float)dbm_value_1310);
|
||
length = strlen(JsonOutputBuffer);
|
||
}
|
||
else
|
||
{
|
||
for (char i = 0; i < 49; i++)
|
||
{
|
||
sprintf(temp, "%.3f,", Calculate_1310_dbm_array[i]);
|
||
strcat(array, temp);
|
||
}
|
||
sprintf(temp, "%.3f", Calculate_1310_dbm_array[49]);
|
||
strcat(array, temp);
|
||
sprintf(JsonOutputBuffer, "{\"version\":\"%s\",\"build\":\"%s\",\"addZoneTime\": %llu,\"TimeStamp\": %llu ,\
|
||
\"bootResult\": %d,\"log\":\"%s\",\"Diff_detail_Record\": %f,\"ADC_Value\": %.4f,\"Channel_1310\": %d,\"i_count_no\": %d,\"i_count_off_bed\": %d,\
|
||
\"i_count_No_Breath\": %d,\"i_count_max\": %f,\"FFT_br\": %f,\"Diff\": %f,\"Diff_Detail\": %f,\"OPM\": %f,\"OPM_Record\": %f,\"OPM_Record_2\": %f,\
|
||
\"OPM_Origin\": %f,\"Ratio[0]\": %f,\"Ratio[1]\": %f,\"Peak[0]\": %f,\"Peak[1]\": %f,\"Peak[2]\": %f,\"Peak[3]\": %f,\"HR_result\": %d,\"time_result\": %d,\
|
||
\"EnergyData\": %d}",
|
||
UploadVersion, BuildTimeString,
|
||
(timeClockCount_Send + (((signed char)warning_config.timeZone) * 60 * 60 * 1000)), timeClockCount_Send, bootResult,
|
||
MyStr, (float)Diff_detail_Record, ADC_1310, channel_1310, i_count_no_human, i_count_off_bed, i_count_No_Breath, (float)i_count_Max,
|
||
(float)FFT_br, (float)Diff, (float)Diff_Detail, (float)OPM_Current, (float)OPM_Record, (float)OPM_Record_2, (float)OPM_Original,
|
||
(float)(stash_Ratio[0]), (float)(stash_Ratio[1]), (float)(HeartValueRes2Peaks[0]), (float)(HeartValueRes2Peaks[1]),
|
||
(float)(HeartValueRes2Peaks[2]), (float)(HeartValueRes2Peaks[3]), fft_HeartBeatRate_Result, time_HeartBeatRate_Result, EnergyData);
|
||
length = strlen(JsonOutputBuffer) + strlen(array);
|
||
}
|
||
// printf("%d JSON OUTPUT: %s \n", length, JsonOutputBuffer);
|
||
str[0] = 0XA5;
|
||
str[1] = 0x5A;
|
||
str[2] = length & 0xff;
|
||
str[3] = length >> 8;
|
||
str[4] = 0x2E;
|
||
memcpy(str + 5, JsonOutputBuffer, strlen(JsonOutputBuffer));
|
||
#if SLEEP_DEBUG_MODE
|
||
#else
|
||
USART1_SendData((uint8_t *)str, strlen(JsonOutputBuffer) + 5);
|
||
#endif
|
||
delay_ms(50);
|
||
}
|
||
|
||
/**
|
||
* @function: wifiSendMsgOneMoreTimes
|
||
* @brief: None
|
||
* @param {uint8_t} *data
|
||
* @param {uint32_t} length
|
||
* @param {char} Times
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void wifiSendMsgOneMoreTimes(uint8_t *data, uint32_t length, char Times)
|
||
{
|
||
for (char i = 0; i < Times; i++)
|
||
{
|
||
delay_ms(1200);
|
||
wifi_crc_send(data, length);
|
||
delay_ms(1200);
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function:CheckCoiledData
|
||
* @brief 判断有没有连续
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void CheckCoiledData(void)
|
||
{
|
||
// 判断有没有连续
|
||
if (!OverTime_CheckFlag && OverTime_Count >= REPORT_OVERTIME)
|
||
{
|
||
int i = 0;
|
||
for (i = 0; i < REPORT_OVERTIME; i++)
|
||
{
|
||
if (BreathRateBuffer[i] == 0)
|
||
break;
|
||
}
|
||
if (i == REPORT_OVERTIME) // 连续
|
||
{
|
||
OverTime_CheckFlag = 1;
|
||
Array_Count = REPORT_OVERTIME - 1;
|
||
}
|
||
else // 不连续 清除
|
||
{
|
||
Array_Count = 0;
|
||
OverTime_Count = 0;
|
||
OverTime_CheckFlag = 0;
|
||
ClearReportBuffer();
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function:delateLastAwayBedData
|
||
* @brief 删除最后一包睡眠报告中离床数据
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
uint16_t delateLastAwayBedData(uint16_t Array_Size, char *Buffer)
|
||
{
|
||
uint16_t index = 0;
|
||
// 去除最后的离床数据
|
||
for (int i = Array_Size - 1; i >= 0; i--)
|
||
{
|
||
// printf("TestBuffer[%d] = %d\n", i, *(Buffer + i));
|
||
if (*(Buffer + i) == 0 && *(Buffer + (i - 1)) == 0)
|
||
{
|
||
// printf("Count ++\r\n");
|
||
}
|
||
else
|
||
{
|
||
index = i;
|
||
// printf("index = %d\r\n", index);
|
||
return index;
|
||
}
|
||
}
|
||
return Array_Size;
|
||
}
|
||
|
||
/**
|
||
* @function: sleepReportClearData
|
||
* @brief 睡眠报告清除
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void sleepReportClearData(void)
|
||
{
|
||
// 清除存储的睡眠报告
|
||
ClearReportBuffer();
|
||
Array_Count = 0;
|
||
InBedTimeStamp = 0;
|
||
OverTime_Count = 0;
|
||
OverTime_CheckFlag = 0;
|
||
}
|
||
/**
|
||
* @function: sleepReportLastPack
|
||
* @brief 睡眠报告最后离床上报清除
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void sleepReportLastPack(void)
|
||
{
|
||
char SleepHours[128] = {0};
|
||
reportTimeClock = timeClockCount + ((signed char)warning_config.timeZone) * 60 * 60 * 1000;
|
||
IWDG_Feed(); // NOTE:喂狗
|
||
// TODO: 进行最后的睡眠报告的上报
|
||
printf("Sleep Last Package!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\r\n");
|
||
Array_Count = delateLastAwayBedData(Array_Count, HeartRateBuffer);
|
||
// SleepReportGenerate(timeClockCount_Send, Array_Count, 6);
|
||
// 清除存储的睡眠报告
|
||
sleepReportClearData();
|
||
bodyCheckSignal = BODY_CHECK_ENABLE;
|
||
}
|
||
|
||
/**
|
||
* @function: bubbleSort
|
||
* @brief: None
|
||
* @param {int} a
|
||
* @param {int} n
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void bubbleSort(int a[], int n)
|
||
{
|
||
int i, t;
|
||
for (i = 0; i < n - 1; i++)
|
||
{
|
||
for (int j = 0; j < n - 1; j++)
|
||
if (a[j] < a[j + 1])
|
||
{
|
||
t = a[j];
|
||
a[j] = a[j + 1];
|
||
a[j + 1] = t;
|
||
}
|
||
}
|
||
}
|
||
|
||
/**
|
||
* @function: checkCounters
|
||
* @brief: None
|
||
* @param {int} a
|
||
* @return {*}
|
||
* @author: lzc
|
||
*/
|
||
void checkCounters(uint8_t Breath, uint8_t Heart)
|
||
{
|
||
// NOTE: Check if br in range
|
||
if (Breath >= 11 && Breath <= 12)
|
||
bR_warningCounter[0]++;
|
||
else if (Breath >= 13 && Breath <= 15)
|
||
bR_warningCounter[1]++;
|
||
else if (Breath >= 16 && Breath <= 18)
|
||
bR_warningCounter[2]++;
|
||
else if (Breath >= 19 && Breath <= 20)
|
||
bR_warningCounter[3]++;
|
||
// NOTE: Check if Hr in range
|
||
if (Heart >= 61 && Heart <= 65)
|
||
hR_warningCounter[0]++;
|
||
else if (Heart >= 66 && Heart <= 70)
|
||
hR_warningCounter[1]++;
|
||
else if (Heart >= 71 && Heart <= 75)
|
||
hR_warningCounter[2]++;
|
||
else if (Heart >= 76 && Heart <= 80)
|
||
hR_warningCounter[3]++;
|
||
else if (Heart >= 81 && Heart <= 85)
|
||
hR_warningCounter[4]++;
|
||
else if (Heart >= 86 && Heart <= 90)
|
||
hR_warningCounter[5]++;
|
||
// NOTE: Out of range
|
||
if ((Breath < 7 || Breath >= 30) && Breath != 0)
|
||
{
|
||
memcpy(count_br, bR_warningCounter, sizeof(bR_warningCounter));
|
||
bubbleSort(count_br, 4);
|
||
if (count_br[0] == bR_warningCounter[0])
|
||
Breath = 11;
|
||
else if (count_br[0] == bR_warningCounter[1])
|
||
Breath = 14;
|
||
else if (count_br[0] == bR_warningCounter[2])
|
||
Breath = 17;
|
||
else if (count_br[0] == bR_warningCounter[3])
|
||
Breath = 19;
|
||
else
|
||
Breath = 20;
|
||
// WarnMsg_CheckStatus(count_br[0], Heart, body_movement_value);
|
||
BreathRateWarn = Breath;
|
||
printf("Upload Breath is %d\n", Breath);
|
||
}
|
||
if ((Heart < 45 || Heart >= 110) && Heart != 0)
|
||
{
|
||
memcpy(count_hr, hR_warningCounter, sizeof(hR_warningCounter));
|
||
bubbleSort(count_hr, 6);
|
||
if (count_hr[0] == hR_warningCounter[0])
|
||
Heart = 64;
|
||
else if (count_hr[0] == hR_warningCounter[1])
|
||
Heart = 68;
|
||
else if (count_hr[0] == hR_warningCounter[2])
|
||
Heart = 73;
|
||
else if (count_br[0] == hR_warningCounter[3])
|
||
Heart = 78;
|
||
else if (count_br[0] == hR_warningCounter[4])
|
||
Heart = 83;
|
||
else if (count_br[0] == hR_warningCounter[5])
|
||
Heart = 88;
|
||
else
|
||
Heart = 90;
|
||
// WarnMsg_CheckStatus(Breath, count_hr[0], body_movement_value);
|
||
HeartBeatRateWarn = Heart;
|
||
printf("Upload Heart is %d\n", Heart);
|
||
}
|
||
}
|