寫在前面
本文分享的是一種基于查表法的水流量的算法方案設計與實現,算法簡單易懂,主要面向初學者,有兩個目的:一是給初學者一些算法設計的思路引導;二是引導初學者學習怎樣用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} qmax?qmax的值是多少?
答:設定值 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;
}
參考源碼
源碼鏈接
很高興能幫助到你!