写在前面
本文分享的是一种基于查表法的水流量的算法方案设计与实现,算法简单易懂,主要面向初学者,有两个目的:一是给初学者一些算法设计的思路引导;二是引导初学者学习怎样用C语言编程实现。
一、设计需求
-
基于“1990年国际温标纯水密表”,通过查表法求出水密度,下图是表的部分截图。
-
线性信号(电磁流量计、4-20mA 输出涡街)流量公式:
q = q m a x ⋅ x A ⋅ k ρ q=q_{max}\cdot x_A \cdot k_\rho q=qmax⋅xA⋅kρ
式中:
q
m
a
x
q_{max}
qmax:满量程流量,单位与瞬时流量相同。
x
A
x_A
xA:测量流量的模拟信号,0~100% (来自差压变送器未开方信号)。
k
ρ
k_\rho
kρ:为补偿信号(无补偿设为1.0)。
k ρ = ρ i ρ d k_\rho=\frac{\rho_i}{\rho_d} kρ=ρdρi
式中:
ρ
i
\rho_i
ρi:水的工作密度根据测量的温度也是查表得到,kg/m3。
ρ
d
\rho_d
ρd:设计状态下蒸汽、水的密度(见生产单位出厂计算书),kg/m3。
注:蒸汽应有三个数表 (下面三个表均按照《1967IFC公式》)
(1)过热蒸汽密度表;
(2)饱和蒸汽(以压力自变量)密度表;
(3)饱和蒸汽(以温度自变量)密度表;
数表范围大小可根据用户适用范围确定。
二、算法分析
-
问题1: q m a x q_{max} qmaxqmax的值是多少?
答:设定值 0~999999999。
-
问题2:差压变送器的信号是什么?从哪里获得?
答:4~20mA,变送器输出。
-
问题3:是否需要补偿信号?若需要回答以下问题。
答:需要补偿(更精确)
-
问题4:计算 ρ i \rho_i ρi需要的“表”请提供。
答:查阅文献,下载表。
-
问题5: ρ d \rho_d ρd的值是多少?
答:设定值0~999999999。
-
问题6:本项目是水还是蒸汽?若是蒸汽则用哪个表,请提供表。
答:电磁测量的是水,按水的密度表。
三、算法实现
- 实现语言:C语言
- 测试环境:VSCode + GCC
程序包括三个文档,如下表:
文件名称 | 包含函数 | 功能 |
---|---|---|
main.c | main() | 主函数,在该函数内编写测试用例 |
flowrate.c | (1)LinearFlowRate() (2)GetDensity() (3)Search_Bin (4)Destroy() (5)Creat_SeqFromTab> | (1)求水的线性信号流量 (2)求密度,被LinearFlowRate调用 (3)在有序表中折半查找 (4)释放空间 (5)创建有序表 |
flowrate.h | LinearFlowRate函数声明 | 在H文件中声明的函数,可以被外部调用。 |
部分源码如下:
flowrate.c
/******************************************************************************************/
//功 能:求水的线性信号流量
//参 数:setQmax:满量程流量,单位与瞬时流量相同,人为设定,取值0~999999999
// setDensity:设置状态下蒸汽、水的密度,单位kg/m3,人为设定,取值0~999999999
// transmitterSignal:测量流量的模拟信号,取值0~100%,由4~20mA,压差变送器输出
// temperature:实际采集的温度值
//返 回 值:实际的流量值
//作 者:MJY@二进制
//修改时间:2023-12-11
/*****************************************************************************************/
float LinearFlowRate(long setQmax,long setDensity, float transmitterSignal, float temperature )
{
long density;
int te;
float realFlowrate;
te = (int)(temperature*10); //实际温度乘10是为了查表,表里对应的温度就是实际值的10倍。
if ( (te > 409) && (te < 499) ) te = 409; //这里做判断是因为水密度表里的温度在509-599,609-699,709-799,809-899,909-999没有。
else if ((te > 509) && (te < 599)) te = 509;
else if ((te > 609) && (te < 699)) te = 609;
else if ((te > 709) && (te < 799)) te = 709;
else if ((te > 809) && (te < 899)) te = 809;
else if ((te > 909) && (te < 999)) te = 909;
density = GetDensity(te);
if (density)
{
realFlowrate = setQmax * transmitterSignal * ((density / 1000.0) / setDensity); // (density / 1000.0)密度除以1000是因为表中密度是原来的一千倍,除以1000.0不是1000是为了不省略小数值。
return realFlowrate;
}
else//密度返回0表示,表中未找到相对应的温度值
{
return 0.0; //返回0.0代表发生错误
}
}
main.c
#include "flowrate.h"
#include <stdio.h>
int main()
{
float realFlowrate;
realFlowrate = LinearFlowRate(1000, 1000, 0.5, 28.7);
printf("%f\n", realFlowrate);
system("pause");
return 0;
}
参考源码
源码链接
很高兴能帮助到你!