X2UWaterWmbusEEI/app/UWater_TemperatureCalculate...

779 lines
30 KiB
C
Raw Permalink 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 "UWater_gp22_app.h"
#include "UWater_lcd_app.h"
#include "UWater_frame_app.h"
#include "UWater_TemperatureCalculate_app.h"
#include "UWater_gp22_driver.h"
#include "UWater_rtcc_driver.h"
//0-100℃对应的超声波速度 单位m/s
const float sound_speed_in_water[101]=
{1402.336,
1407.31196 ,1412.173988,1416.924022,1421.563966,1426.095691,
1430.521033,1434.841795,1439.059749,1443.176633,1447.194154,
1451.113987,1454.937777,1458.667135,1462.303645,1465.84886 ,
1469.304301,1472.671463,1475.95181 ,1479.146777,1482.257772,
1485.286175,1488.233337,1491.100583,1493.889211,1496.600493,
1499.235674,1501.795973,1504.282585,1506.69668 ,1509.039401,
1511.311869,1513.515181,1515.65041 ,1517.718606,1519.720794,
1521.657981,1523.531149,1525.341257,1527.089246,1528.776035,
1530.40252 ,1531.969579,1533.478071,1534.928834,1536.322685,
1537.660427,1538.942839,1540.170687,1541.344717,1542.465656,
1543.534218,1544.551096,1545.51697 ,1546.432504,1547.298344,
1548.115124,1548.88346 ,1549.603957,1550.277204,1550.903775,
1551.484234,1552.01913 ,1552.508999,1552.954367,1553.355746,
1553.713636,1554.028529,1554.300904,1554.53123 ,1554.719965,
1554.86756 ,1554.974453,1555.041077,1555.067854,1555.055198,
1555.003516,1554.913207,1554.784663,1554.61827 ,1554.414405,
1554.173443,1553.89575 ,1553.581689,1553.231616,1552.845885,
1552.424843,1551.968835,1551.478204,1550.953285,1550.394416,
1549.801928,1549.176154,1548.517423,1547.826062,1547.102399,
1546.346762,1545.559476,1544.740868,1543.891267,1543.011 ,
};
#if WENDU_FANSUAN_OPEN
/*-----------------------------------------------------------------------------*/
TEMP_IVVERSE_UNION_MSG temp_inverse_struct_msg;//温度反算对外消息联合体
Temp_Inverse_Data1 Temp_Inverse_Data;//反算温度对于单程时间处理
//单程时间滤波相关参数
u32 gp30_tof_up_down_head =0;//
u32 gp30_tof_up_down_length=0;
u32 gp30_tof_up_data[MAX_TEMP_NUM]; //用于采集up单程时间 2020-12-05
u32 gp30_tof_down_data[MAX_TEMP_NUM]; //用于采集up单程时间 2020-12-05
u32 gp30_tof_up_filter_value =0;//up滤波值
u32 gp30_tof_down_filter_value =0;//down滤波值
//单程时间校准插值相关参数
u8 gp30_tof_buchang_head =0;
u8 gp30_tof_buchang_length =0;
float gp30_tof_up_chazhi_filter_value =0;//up滤波值
float gp30_tof_down_chazhi_filter_value =0;//down滤波值
float gp30_tof_up_buchang_data[MAX_TOF_BUCHANG_NUM]={0};
float gp30_tof_down_buchang_data[MAX_TOF_BUCHANG_NUM]={0};
u8 tof_caliberate_state = TOF_BUCHANG_IDLE;//空闲状态不采集数据
//单程时间原始数据存储BUF
static u32 s_g_fhl_tof_up_data[GP22_APP_TEMP_INVERSE_DATA_SIZE_FIVE]={0}; //FHL_TOF_UP采集队列
static u32 s_g_fhl_tof_down_data[GP22_APP_TEMP_INVERSE_DATA_SIZE_FIVE]={0}; //FHL_TOF_DOWN采集队列
u32 tof_down_data[MAX_TEMP_NUM]={0};//记录down的单程时间中与UP单程时间对应位置的数据
//继承变量
extern GP30_SYS_Date gp22_app_data; //gp22当前数据
extern GP30_SYS_Date gp22_test_data; //gp22检定状态下当前数据
extern GP30_APP_SAVE_DATA g_sample_save_data; //当前数据备份
extern u32 s_g_up_am[GP22_APP_TEMP_INVERSE_DATA_SIZE+GP22_APP_TEMP_INVERSE_DATA_SIZE]; //am采集队列 数组中前4个存储第4~第7个波形振幅后4个存储第8~第11个波形振幅
extern u32 s_g_down_am[GP22_APP_TEMP_INVERSE_DATA_SIZE+GP22_APP_TEMP_INVERSE_DATA_SIZE]; //down采集队列 数组中前4个存储第4~第7个波形振幅后4个存储第8~第11个波形振幅
extern float temp_calculate_last;
/*-----------------------------------------------------------------------------*/
/*温度反算流程第一步:单程时间与振幅数据采集与处理*/
/****************************************************************
Function: void Tof_And_AM_Data_Collect(u8 i,u32 s_g_tof_am_pointer)
Description: 采集GP30给的up和down单程时间、up和down对应的振幅
函数性质: 外部接口函数
*****************************************************************/
void Tof_And_AM_Data_Collect(u8 i,u32 s_g_tof_am_pointer)
{
u32 s_g_tof_am_data[GP22_APP_QUEUE_SIZE]={0};
s_g_tof_am_data[i] = s_g_tof_am_pointer;
s_g_tof_am_data[i] = (s_g_tof_am_data[i] & 0x000000FFU) << 24 | (s_g_tof_am_data[i] & 0x0000FF00U) << 8 | (s_g_tof_am_data[i] & 0x00FF0000U) >> 8 | (s_g_tof_am_data[i] & 0xFF000000U) >> 24; //大小端转换
//温度反算传上来的TOF值和振幅值处理详见设计文档里传输的数据内容
if((0==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)&&(i!=GP22_APP_QUEUE_SIZE-1))//传输的第1 4 7 10 13个数据为FHL 5-9波的up单程时间
{
s_g_fhl_tof_up_data[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i];//传输的第1 4 7 10 个数据为FHL 5-9波的up单程时间
}
else if(1==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)//传输的第2 5 8 11 14 个数据为FHL 5-9波的down单程时间
{
s_g_fhl_tof_down_data[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i];//传输的第2 5 8 11 14 个数据为FHL 5-9波的down单程时间
}
else if((2==i%GP22_APP_TEMP_INVERSE_DATA_SIZE)||(i==GP22_APP_QUEUE_SIZE-1))//传输的第3 6 9 12 15 16 个数据为FHL 5-10波的up(左移16位高16)|down(低16位)单程时间
{
s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i]>>16;//获取UP的振幅
if(0xF000==(s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]&0xF000))//如果振幅F开头说明是负的振幅负振幅处理为0
{
s_g_up_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=0;
}
s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=s_g_tof_am_data[i]&0x0000FFFF;//获取DOWN的振幅
if(0xF000==(s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]&0xF000))//如果振幅F开头说明是负的振幅负振幅处理为0
{
s_g_down_am[i/GP22_APP_TEMP_INVERSE_DATA_SIZE]=0;
}
}
}
/****************************************************************
Function: void Tof_Calcuate_Average(u32 *tof_up, u32 *tof_down, u8 data_len)
Description: 分别对up 和Down 单程时间求取平均值
函数性质: 内部函数
*****************************************************************/
void Tof_Calcuate_Average(u32 *tof_up, u32 *tof_down, u8 data_len)
{
u8 i = 0;
u32 sum_tof_up=0,sum_tof_down=0;
for(i = 0;i< data_len;i++)
{
sum_tof_up += tof_up[i];//求取UP单程时间均值
sum_tof_down += tof_down[i];//求取Down单程时间均值
}
if((sum_tof_up!=0)&&(sum_tof_down!=0))//无水情况下 单程时间为零
{
gp22_test_data.s.TOF_up = (sum_tof_up/data_len)-TOF_6_US;//将up的单程时间平均值与6us做差后给到TOF_UP
gp22_test_data.s.TOF_down = (sum_tof_down/data_len)-TOF_6_US;//将up的单程时间平均值与6us做差后给到TOF_DOWN
}
else
{
gp22_test_data.s.TOF_up = 0;
gp22_test_data.s.TOF_down=0;
}
}
/****************************************************************
Function: AM_Calcuate_Average(u32 *up_am, u32 *down_am, u8 data_len)
Description: 分别对up 和Down 振幅求取平均值
函数性质: 内部函数
*****************************************************************/
void AM_Calcuate_Average(u32 *up_am, u32 *down_am, u8 data_len)
{
u8 i = 0,down_am_cnt=0,up_am_cnt=0;
u32 sum_am_up=0,sum_am_down=0;
for(i = 0;i< data_len;i++)
{
if((s_g_up_am[i]>0)&&(s_g_up_am[i]<UP_AM_MAX))
{
sum_am_up += s_g_up_am[i];
up_am_cnt++;
}
if((s_g_down_am[i]>0)&&(s_g_down_am[i]<DOWN_AM_MAX))
{
sum_am_down += s_g_down_am[i];
down_am_cnt++;
}
}
if(down_am_cnt!=0)
{
Temp_Inverse_Data.Temp_Inverse_Data.down_am_average = sum_am_down / down_am_cnt;//求取Up振幅均值
}
else
{
Temp_Inverse_Data.Temp_Inverse_Data.down_am_average = 0;//求取Down振幅均值
}
if(up_am_cnt!=0)
{
Temp_Inverse_Data.Temp_Inverse_Data.up_am_average = sum_am_up / up_am_cnt;//求取UP振幅均值
}
else
{
Temp_Inverse_Data.Temp_Inverse_Data.up_am_average = 0;//求取UP振幅均值 = 0;
}
}
/***************************************************************
函数名称: Gp30_Tof_Save(void)
功 能; 单程时间采集函数----分别将up和down的单程时间存储到相应的BUFFER中
函数性质: 内部函数
****************************************************************/
void Gp30_Tof_Save(void)
{
gp30_tof_up_data[gp30_tof_up_down_head] = gp22_test_data.s.TOF_up; //将单程时间存入到数组中
gp30_tof_down_data[gp30_tof_up_down_head]= gp22_test_data.s.TOF_down; //将单程时间存入到数组中
gp30_tof_up_down_head++;
if(MAX_TEMP_NUM!=gp30_tof_up_down_head)//采样数组满了一次
{
if(gp30_tof_up_down_length != MAX_TEMP_NUM)//当BUF中数据已经存满一次了
{
gp30_tof_up_down_length = gp30_tof_up_down_head;//
}
}
else
{
gp30_tof_up_down_length = MAX_TEMP_NUM;
}
gp30_tof_up_down_head %= MAX_TEMP_NUM;
}
/****************************************************************
Function: 单程时间滤波函数
Description:*p 指向单程时间数组首地址 len 数据长度 flag 0:tof_up 1:tof_down
函数性质: 内部函数
*****************************************************************/
u32 Filter_FOR_TOFDOWN(u32 *p, u8 len) //
{
u8 i,cnt=0,max_count=0,min_count=0;//max_count:记录大数单程时间个数 min_count:记录小数单程时间个数
u32 sum=0,sum_max=0,sum_min=0,tof_max=0,tof_min=0,tof_dif_max=0,tof_dif_min=0,tof_current=0;/*sum:单程时间累加和;sum_max大数单程时间之间累加和
sum_min大数单程时间之间累加和 tof_max:最大单程时间
tof_min:最小单程时间 tof_dif_max最大单程时间与各个单程时间的差值
tof_dif_min:最大单程时间与各个单程时间的差值 tof_current: 本次计算得到的单程时间*/
static u32 tof_down_last=0;//记录up和down的上次数值的单程时间
if(0==tof_down_data[0])
{
tof_current = tof_down_last;
return tof_current;
}
for(i=0;i<len;i++)
{
if(0==tof_down_data[i])
{
break;//确定数据长度
}
}
cnt = i;//记录有效数据个数
if(1==cnt)
{
tof_current = tof_down_data[0];
tof_down_last = tof_current; //存储上次的单程时间滤波值
return tof_current;
}
tof_max = tof_down_data[0];
tof_min = tof_down_data[0];
//找到最大 最小值
for(i=0;i<cnt;i++)
{
if((tof_down_data[i]>=tof_max))
{
tof_max = tof_down_data[i];
}
if((tof_down_data[i]<=tof_min))
{
tof_min = tof_down_data[i];
}
}
//判定
for(i=0;i<cnt;i++)
{
tof_dif_max = tof_max - tof_down_data[i];
if(tof_dif_max <= TOF_MAX_DIF_FOR_HUADONG)//200ns
{
max_count++;
sum_max += tof_down_data[i];
}
tof_dif_min = tof_down_data[i] - tof_min;
if(tof_dif_min <= TOF_MAX_DIF_FOR_HUADONG)
{
min_count++;
sum_min +=tof_down_data[i];
}
}
//比较最大、最小个数的大小
if(max_count==min_count)//
{
if((tof_max-tof_min) <= TOF_MAX_DIF_FOR_HUADONG)
{
tof_current = sum_max / max_count;//计算本次单程时间滤波值
}
else
{
tof_current = tof_down_last; //存储上次的单程时间滤波值
}
}
else if(max_count>min_count)
{
len = max_count;
sum = sum_max ;
tof_current = sum / len;//计算本次单程时间滤波值
}
else
{
len = min_count;
sum = sum_min;
tof_current = sum / len;//计算本次单程时间滤波值
}
//先判断合法性,再进行赋值
if(tof_current!=0)
{
tof_down_last = tof_current; //存储上次的单程时间滤波值
}
else
{
tof_current = tof_down_last;
}
return tof_current;
}
/****************************************************************
Function: 单程时间滤波函数
Description:*p 指向单程时间数组首地址 len 数据长度 flag 0:tof_up 1:tof_down
函数性质: 内部函数
*****************************************************************/
u32 Filter_FOR_TOFUP(u32 *tof_up, u32 *tof_down, u8 len) //
{
u8 i,max_count=0,min_count=0;//max_count:记录大数单程时间个数 min_count:记录小数单程时间个数
u32 sum=0,sum_max=0,sum_min=0,tof_max=0,tof_min=0,tof_dif_max=0,tof_dif_min=0,tof_current=0;/*sum:单程时间累加和;sum_max大数单程时间之间累加和
sum_min大数单程时间之间累加和 tof_max:最大单程时间
tof_min:最小单程时间 tof_dif_max最大单程时间与各个单程时间的差值
tof_dif_min:最大单程时间与各个单程时间的差值 tof_current: 本次计算得到的单程时间*/
static u32 tof_up_last=0;//记录up和down的上次数值的单程时间
u32 temp_max[MAX_TEMP_NUM]={0},temp_min[MAX_TEMP_NUM]={0};//统计
tof_max = tof_up[0];
tof_min = tof_up[0];
if(len==1)
{
tof_current = tof_up[0];
tof_up_last = tof_current; //存储上次的单程时间滤波值
tof_down_data[0] = tof_down[0];//
return tof_current;
}
//找到最大 最小值
for(i=0;i<len;i++)
{
if((tof_up[i]>=tof_max))
{
tof_max = tof_up[i];
}
if((tof_up[i]<=tof_min))
{
tof_min = tof_up[i];
}
}
//查看最大和最小值是否同为一个量级
for(i=0;i<len;i++)
{
tof_dif_max = tof_max - tof_up[i];
if(tof_dif_max <= TOF_MAX_DIF_FOR_HUADONG)//200ns
{
temp_max[max_count]= tof_down[i];
max_count++;
sum_max += tof_up[i];
}
tof_dif_min = tof_up[i] - tof_min;
if(tof_dif_min <= TOF_MAX_DIF_FOR_HUADONG)
{
temp_min[min_count]= tof_down[i];
min_count++;
sum_min +=tof_up[i];
}
}
//比较最大、最小个数的大小
if(max_count==min_count)//
{
if(max_count == MAX_TEMP_NUM)
{
tof_current = sum_max / max_count;//计算本次单程时间滤波值
memcpy(tof_down_data,temp_max,MAX_TEMP_NUM*4);
}
else
{
tof_current = tof_up_last; //存储上次的单程时间滤波值
memset(tof_down_data,0,MAX_TEMP_NUM*4);
}
}
else if(max_count>min_count)
{
len = max_count;
sum = sum_max ;
tof_current = sum / len;//计算本次单程时间滤波值
memcpy(tof_down_data,temp_max,MAX_TEMP_NUM*4);
}
else
{
len = min_count;
sum = sum_min;
tof_current = sum / len;//计算本次单程时间滤波值
memcpy(tof_down_data,temp_min,MAX_TEMP_NUM*4);
}
//先判断合法性,再进行赋值
if(tof_current!=0)
{
tof_up_last = tof_current; //存储上次的单程时间滤波值
}
else
{
tof_current = tof_up_last;
}
return tof_current;
}
/***************************************************************
函数名称: Gp30_TOF_and_DOWN_Data_Collect(void)
功 能; 单程时间采集与处理函数 1、单程时间采集 2、单程时间滤波
函数性质: 外部接口函数
****************************************************************/
void Gp30_Tof_Collect_and_Deal()
{
Tof_Calcuate_Average(s_g_fhl_tof_up_data,s_g_fhl_tof_down_data,5);//对单程时间进行滤波
Gp30_Tof_Save();//存储滤波后的单程时间
gp30_tof_up_filter_value = Filter_FOR_TOFUP(gp30_tof_up_data,gp30_tof_down_data,gp30_tof_up_down_length);//
gp30_tof_down_filter_value = Filter_FOR_TOFDOWN(tof_down_data,gp30_tof_up_down_length);//
AM_Calcuate_Average(s_g_up_am,s_g_down_am,6);//振幅均值计算
}
/*温度反算流程第二步1、单程时间校准 2、校准后单程时间进行计算温度*/
/***************************************************************
函数名称: 单程时间校准函数
功 能; time_dof_temp_float 用于计算流速 time_tof_up_floatUp单程时间 time_tof_up_floatDown单程时间
函数性质: 内部函数
****************************************************************/
void Water_Meter_Caliberate(u32 time_dof,float time_tof_up_float,float time_tof_down_float)
{
float time_tof_up_xishu = 0,time_tof_down_xishu = 0;
float temp_jiaozhun=0;//获取表计校准温度
float sound_speed_C = 0;//声速
float calculate_decimal ; //温度的小数部分
float time_tof_up_float_jiaozhun_value =0;//校准的UP单程时间
float time_tof_down_float_jiaozhun_value =0;//校准的DOWN单程时间
u8 calculate_num=0;
float time_dof_temp_float=0;
if(tof_caliberate_state==TOF_BUCHANG_START_SAMPLE)//表计如果处于采样状态就进行
{
temp_jiaozhun = Get_Temperature_Caliberate();//获取台子下发的温度值---待接收接口函数
if((temp_jiaozhun < 0) || (temp_jiaozhun > 100)) //异常温度判断,防止数组越界
{
sound_speed_C = sound_speed_in_water[20];
}
else
{
calculate_num = (u8) (temp_jiaozhun); //查表位置
calculate_decimal = temp_jiaozhun - calculate_num; //温度的小数部分
sound_speed_C = sound_speed_in_water[calculate_num] + calculate_decimal * (sound_speed_in_water[calculate_num + 1] - sound_speed_in_water[calculate_num]);
}
time_dof_temp_float = Gp30DataToFloat(time_dof); //先把有效时间差转换成浮点数
time_dof_temp_float = time_dof_temp_float * (float)250;// 将us转换成真实的ns /4 *1000=ns
float ins_flow_rate_float = sound_speed_C * sound_speed_C * time_dof_temp_float * LEGENTH_SPEED_SOUND_DAOSHU;//C^2*(t2-t1)/2L---求得理论流速 m/s
time_tof_up_float_jiaozhun_value = LEGENTH_SPEED_SOUND / (sound_speed_C+ins_flow_rate_float); //计算出UP单程时间us
time_tof_down_float_jiaozhun_value = LEGENTH_SPEED_SOUND / (sound_speed_C-ins_flow_rate_float); //计算出DOWN单程时间us
time_tof_up_xishu = time_tof_up_float-time_tof_up_float_jiaozhun_value;//表计实际的Up单程时间与理论单程时间进行做差
time_tof_down_xishu = time_tof_down_float-time_tof_down_float_jiaozhun_value;//表计实际的Down单程时间与理论单程时间进行做差
//以后需要添加分别Up和Down的合法性判断
//合法性判断
if(((time_tof_down_xishu - time_tof_up_xishu)>(float)0.5)||((time_tof_down_xishu - time_tof_up_xishu)<(float)-0.5))
{
time_tof_up_xishu = 0;
time_tof_down_xishu = 0;
}
gp22_app_data.s.up_tof_dif.gp30_float = time_tof_up_xishu;//读取EE中存储的UP单程时间系数
gp22_app_data.s.down_tof_dif.gp30_float = time_tof_down_xishu;//读取EE中存储的DOWN单程时间系数
//补偿值进行滑动滤波-----------------------
gp30_tof_up_buchang_data[gp30_tof_buchang_head] = gp22_app_data.s.up_tof_dif.gp30_float; //将单程时间存入到数组中
gp30_tof_down_buchang_data[gp30_tof_buchang_head]= gp22_app_data.s.down_tof_dif.gp30_float; //将单程时间存入到数组中
gp30_tof_buchang_head++;
if(MAX_TOF_BUCHANG_NUM!=gp30_tof_buchang_head)//采样数组满了一次
{
if(gp30_tof_buchang_length != MAX_TOF_BUCHANG_NUM)//当BUF中数据已经存满一次了
{
gp30_tof_buchang_length = gp30_tof_buchang_head;
}
}
else
{
gp30_tof_buchang_length = MAX_TOF_BUCHANG_NUM;
}
gp30_tof_buchang_head %= MAX_TOF_BUCHANG_NUM;
//-------------防护收不到下发温度系数的情况发生!!!!!!!
// if(gp30_tof_buchang_length == MAX_TOF_BUCHANG_NUM)
// {
// FrameClearMsgApp(MsgCaliberate);//清零单程时间校准标志
// GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);
// }
}
}
/***************************************************************
函数名称: 反算温度
功 能; time_dof_temp_float 用于计算流速
函数性质: 外部接口函数
****************************************************************/
void Water_Meter_Temp_calculate(u32 time_dof_temp_float)
{
float time_tof_temp_float =0,temp_calculate_app=0,temp_buchang_chazhi=0,wendu=0;//time_tof_temp_floatup和Down 的单程时间倒数和变量
float time_tof_up_float =0,time_tof_down_float =0;//实时的单程时间
u32 heat_temp = 0;
float heat_temp_xishu=0;//出口温度浮点数类型
if((gp22_test_data.s.TOF_up==0)||(gp22_test_data.s.TOF_down==0))//单程时间为0----认为是空管状态
{
Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_up_filter_value_test = 0;//空管下UP单程时间清零
Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_down_filter_value_test = 0;//空管下DOWN单程时间清零
GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);//这里可以有效预防NB上位机导致表计校准
return;
}
heat_temp = FrameCheckParaApp(FramePara_Tc0);//获取出口温度补偿系数
if(heat_temp >= 0x80000000)//判定补偿系数的正负号
{
heat_temp &= 0x7FFFFFFF;
heat_temp_xishu= 0- Gp30DataToFloat(heat_temp);
}
else
{
heat_temp_xishu = Gp30DataToFloat(heat_temp);
}
time_tof_up_float = Gp30DataToFloat(gp30_tof_up_filter_value)/(float)4; //UP单程时间---转化为us
time_tof_down_float = Gp30DataToFloat(gp30_tof_down_filter_value)/(float)4;//Down单程时间---转化为us
Water_Meter_Caliberate(time_dof_temp_float,time_tof_up_float,time_tof_down_float);//判断是否需要校准单程时间
//1、单程时间修正-----
time_tof_up_float = time_tof_up_float - gp22_app_data.s.up_tof_dif.gp30_float;
time_tof_down_float = time_tof_down_float - gp22_app_data.s.down_tof_dif.gp30_float;
Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_up_filter_value_test = FloatToGp30Data(time_tof_up_float)*(float)4;//活塞台子的单程时间---GP30格式
Temp_Inverse_Data.Temp_Inverse_Data.gp30_tof_down_filter_value_test = FloatToGp30Data(time_tof_down_float)*(float)4;//活塞台子的单程时间---GP30格式
time_tof_temp_float = (float)1/time_tof_up_float+(float)1/time_tof_down_float;//单程时间转换 1/up + 1/down
#if ROUND_LLGS_WDFS_DN15_BRASS_40KPA_GP30_32768 || Buxiugang_LLGS_WDFS_DN15_BXG_40KPA_GP30_32768 || Plastic_LLGS_WDFS_DN15_PALSTIC_40KPA_GP30_32768
if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_LOW) //小于35度
{
temp_calculate_app = (float)1164325060.28*time_tof_temp_float*time_tof_temp_float*time_tof_temp_float-(float)117666513.36*time_tof_temp_float*time_tof_temp_float + (float)3974951.33*time_tof_temp_float-(float)44879.30;
}
else if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_MIDDLE) //35到45度
{
temp_calculate_app = (float)18099447.719*time_tof_temp_float*time_tof_temp_float - (float)1264215.524*time_tof_temp_float +(float)22102.772;
}
else
{
temp_calculate_app = (float)93075924.43*time_tof_temp_float*time_tof_temp_float -(float)6658976.07*time_tof_temp_float +(float)119144.49;
}
#elif ROUND_LLGS_WDFS_DN20_BRASS_40KPA_GP30_32768 || Buxiugang_LLGS_WDFS_DN20_BXG_40KPA_GP30_32768
if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_LOW) //小于35度
{
temp_calculate_app = (float)1523999897.62*time_tof_temp_float*time_tof_temp_float*time_tof_temp_float-(float)147356593.93*time_tof_temp_float*time_tof_temp_float +(float) 4761092.78*time_tof_temp_float -(float)51396.5;//温度差值补偿
}
else if(time_tof_temp_float <= TOF_UP_DOWN_DAOSHUHE_MIDDLE) //35到45度
{
temp_calculate_app = (float)18709611.192*time_tof_temp_float*time_tof_temp_float -(float)1245577.831*time_tof_temp_float +(float)20757.105 ;
}
else
{
temp_calculate_app = (float)147329123.77*time_tof_temp_float*time_tof_temp_float -(float)10079793.85*time_tof_temp_float +(float)172450.97 ;
}
#endif
temp_calculate_app = temp_calculate_app - temp_buchang_chazhi + heat_temp_xishu;//默认状况下温度系数为0
//3、温度合法性判断
temp_calculate_app = temp_calculate_app - wendu;//算出来温度---暂时不添加任何限制
if((temp_calculate_app<0)||(temp_calculate_app>60))
{
temp_calculate_app = temp_calculate_last;//
}
else
{
#if Buxiugang_LLGS_WDFS_DN15_BXG_40KPA_GP30_32768 || Buxiugang_LLGS_WDFS_DN20_BXG_40KPA_GP30_32768
if(temp_calculate_app<(float)22.8)
{
temp_calculate_app=temp_calculate_app+((float)-0.05*temp_calculate_app+(float)1.54); //不锈钢22.8 - 0度之间需要进行补偿
}
else
{
temp_calculate_app=temp_calculate_app+((float)-0.1296*temp_calculate_app+(float)3.3556); //不锈钢22.8 - 60度之间需要进行补偿
}
#endif
}
temp_calculate_last = temp_calculate_app;
// else //
// {
// temp_calculate_last = temp_calculate_app;//记录上次正常的温度数据-----从有水到无水时 用这个数据
// }
}
/*******************************************************************************
* @fun_name: TempInverseSetMsgApp
* @brief : 置起反算消息类型
* 函数性质 : 外部接口函数
******************************************************************************/
void TempInverseSetMsgApp(TempInverse_MsgTypeDef msgType)
{
if(msgType<TEMP_INVERSE_MSG_TYPE_CNT)
{
temp_inverse_struct_msg.MsgBuf[msgType] = 1;
}
}
/*******************************************************************************
* @fun_name: TempInverseCheckMsgApp
* @brief : 查询反算msg接口
* @param[out]: msg 有消息1 无消息0
******************************************************************************/
u8 TempInverseCheckMsgApp(TempInverse_MsgTypeDef msgType)
{
if(msgType < TEMP_INVERSE_MSG_TYPE_CNT)
{
return temp_inverse_struct_msg.MsgBuf[msgType];
}
else
{
return ERROR;
}
}
/*******************************************************************************
* @fun_name: TempInverseClearMsgApp
* @brief : 清除反算msg接口
* @param[out]: 1成功 0失败
******************************************************************************/
u8 TempInverseClearMsgApp(TempInverse_MsgTypeDef msgType)
{
if(msgType < TEMP_INVERSE_MSG_TYPE_CNT)
{
temp_inverse_struct_msg.MsgBuf[msgType] = 0;
return SUCCESS;
}
else
{
return ERROR;
}
}
/****************************************************************
Function: 单程时间插值补偿系数滤波
Description:*p 指向单程时间补偿系数数组首地址 len 数据长度 ----用于进行单程时间补偿值的滤波
函数性质: 内部函数
*****************************************************************/
float Filter_FOR_TOF_CHAZHI(float *p, u8 len) //
{
u8 i;
float sum=0,tof_current=0,temp_max=p[0],temp_min=p[0];
if(len>3)
{
for(i=0;i<len;i++)
{
if((p[i]>=temp_max))
{
temp_max = p[i];
}
if((p[i]<=temp_min))
{
temp_min = p[i];
}
sum += p[i];
}
tof_current = (sum-temp_min-temp_max) / (len-2);//计算本次单程时间差值滤波值
}
else //用实时数据
{
tof_current = p[len-1];
}
return tof_current;
}
/****************************************
Function: GP30_tof_buchang_filter
Description: 开启和关闭单程时间校准补偿
Return: 0 启动单程时间差值校准 1停止单程时间差值校准 2空管状态下清零校准 3:反算温度滤波
Others: 外部接口函数
****************************************************************/
void GP30_tof_buchang_filter(u8 flag)
{
u8 i=0;
switch (flag)
{
case START_CALIBREATE:
{
gp30_tof_buchang_head = 0;//数值指针头结点
gp30_tof_buchang_length = 0;//数据长度
gp30_tof_up_chazhi_filter_value =0;//up滤波值
gp30_tof_down_chazhi_filter_value =0;//down滤波值
gp22_app_data.s.up_tof_dif.gp30_float = 0;//清零单程时间差值数据
gp22_app_data.s.down_tof_dif.gp30_float = 0;//清零单程时间差值数据
for(i=0;i<MAX_TOF_BUCHANG_NUM;i++)
{
gp30_tof_up_buchang_data[i] = 0; //
gp30_tof_down_buchang_data[i]= 0; //
}
tof_caliberate_state = TOF_BUCHANG_START_SAMPLE;//先进行清零单程时间补偿系数值
break;
}
case STOP_CALIBREATE:
{
if(tof_caliberate_state == TOF_BUCHANG_START_SAMPLE)//如果是采样状态下才刷新数据
{
tof_caliberate_state = TOF_BUCHANG_IDLE;
TempInverseSetMsgApp(TofCaliberateMsg);
if(0!=gp30_tof_buchang_length)
{
gp30_tof_up_chazhi_filter_value = Filter_FOR_TOF_CHAZHI(&gp30_tof_up_buchang_data[0],gp30_tof_buchang_length);
gp30_tof_down_chazhi_filter_value = Filter_FOR_TOF_CHAZHI(&gp30_tof_down_buchang_data[0],gp30_tof_buchang_length);
//计算完毕后需要进行差值补偿合法性判定 介于[-4,4]之间认为合格
if(((gp30_tof_up_chazhi_filter_value)>TOF_COMPENSATION_COEFFICIENT)||((gp30_tof_down_chazhi_filter_value)>TOF_COMPENSATION_COEFFICIENT)|| \
((gp30_tof_up_chazhi_filter_value)< -TOF_COMPENSATION_COEFFICIENT)||((gp30_tof_down_chazhi_filter_value)<-TOF_COMPENSATION_COEFFICIENT))
{
gp30_tof_up_chazhi_filter_value = 0;
gp30_tof_down_chazhi_filter_value = 0;
}
gp22_app_data.s.up_tof_dif.gp30_float = gp30_tof_up_chazhi_filter_value;
gp22_app_data.s.down_tof_dif.gp30_float = gp30_tof_down_chazhi_filter_value;
}
}
break;
}
case NOT_ALLOW_CALIBREATE:
{
tof_caliberate_state = TOF_BUCHANG_IDLE;//空闲状态
gp22_app_data.s.up_tof_dif.gp30_float = g_sample_save_data.s.up_tof_dif.gp30_float;//
gp22_app_data.s.down_tof_dif.gp30_float = g_sample_save_data.s.down_tof_dif.gp30_float;
break;
}
default:
{
break;
}
}
}
/****************************************************************
Function: GetTemperatureCalculateParameter
Description: 获取反算参数 包括up单程时间、down单程时间、up振幅均值、down振幅均值
函数性质: 外部接口函数
*****************************************************************/
u32 GetTemperatureCalculateParameter(u8 flag)
{
if(flag < TemperatureCalculateParameterTotal)
{
return Temp_Inverse_Data.Temp_Inverse[flag];
}
else
{
return ERROR;
}
}
/****************************************************************
Function: void
Description: 反算校准超时查询函数
函数性质: 外部接口函数
*****************************************************************/
void FanSuan_Caliberate_Timeout(void)
{
if(TRUE == FrameCheckMsgApp(MsgCaliberate))//单程时间校准标志查询
{
if(0==RtccCheckTimer(RTCC_TOF_CALIBERATE_TIME))//90s校准超时时间到
{
FrameClearMsgApp(MsgCaliberate);//清零单程时间校准标志
GP30_tof_buchang_filter(NOT_ALLOW_CALIBREATE);
}
}
}
#endif