基于查表法的水流量算法设计与实现

写在前面

本文分享的是一种基于查表法的水流量的算法方案设计与实现,算法简单易懂,主要面向初学者,有两个目的:一是给初学者一些算法设计的思路引导;二是引导初学者学习怎样用C语言编程实现。

一、设计需求

  1. 基于"1990年国际温标纯水密表",通过查表法求出水密度 ,下图是表的部分截图。

  2. 线性信号(电磁流量计、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

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

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

参考源码

源码链接


很高兴能帮助到你!

相关推荐
何曾参静谧19 分钟前
「C/C++」C/C++ 指针篇 之 指针运算
c语言·开发语言·c++
lulu_gh_yu1 小时前
数据结构之排序补充
c语言·开发语言·数据结构·c++·学习·算法·排序算法
~yY…s<#>3 小时前
【刷题17】最小栈、栈的压入弹出、逆波兰表达式
c语言·数据结构·c++·算法·leetcode
EricWang13585 小时前
[OS] 项目三-2-proc.c: exit(int status)
服务器·c语言·前端
我是谁??5 小时前
C/C++使用AddressSanitizer检测内存错误
c语言·c++
希言JY5 小时前
C字符串 | 字符串处理函数 | 使用 | 原理 | 实现
c语言·开发语言
午言若5 小时前
C语言比较两个字符串是否相同
c语言
TeYiToKu7 小时前
笔记整理—linux驱动开发部分(9)framebuffer驱动框架
linux·c语言·arm开发·驱动开发·笔记·嵌入式硬件·arm
互联网打工人no17 小时前
每日一题——第一百二十四题
c语言
爱吃生蚝的于勒7 小时前
深入学习指针(5)!!!!!!!!!!!!!!!
c语言·开发语言·数据结构·学习·计算机网络·算法