- Elde.FlowMeterCouple component added

- LtrPerPulse and LtrPerPulseCorrected property/function added to IFlowMeter and flowmeters
This commit is contained in:
Milan Hanajik
2014-09-10 13:43:33 +02:00
parent fcfdfeca41
commit 3559ab0ab3
16 changed files with 657 additions and 19 deletions
@@ -28,9 +28,19 @@ namespace TBF.BenchControl.Elde.FlowMeter
public readonly ControlBoardDev ControlBoard;
readonly float nominalFlow;
public float NominalFlow { get { return nominalFlow; } }
public float LtrPerPulse { get { return nominalFlow / 7200.0f; } }
public float LtrPerPulseCorrected(float flow)
{
return LtrPerPulse; /// TODO: apply correction
//float corrected = BenchControl.Formulas.CorrectedValue(flow, meterEntity.Corrections);
}
public FlowMeter(FlowMeterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
@@ -24,7 +24,7 @@ namespace TBF.BenchControl.Elde.FlowMeter
public FlowMeterCfg(IComponentFactory factory, string name, string parentName, int idx1, float nominalFlow)
: base(factory, name, parentName)
{
if (idx1 < 0 || idx1 > 5) throw new ArgumentOutOfRangeException("idx1");
if (idx1 < 1 || idx1 > 5) throw new ArgumentOutOfRangeException("idx1");
this.Idx1 = idx1;
this.NominalFlow = nominalFlow;
}
@@ -75,10 +75,10 @@ namespace TBF.BenchControl.Elde.FlowMeter
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 0 || dummy > 5)
if (!int.TryParse(positionTextBox.Text, out dummy) || dummy < 1 || dummy > 7)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Position' should be between 1 and 5";
message += Environment.NewLine + "'Idx1' should be between 1 and 7";
}
float fdummy;
if (!Utils.TryParseUFloat(nominalFlowTextBox.Text, out fdummy) || fdummy < 0.2 || fdummy > 1600)
@@ -15,7 +15,7 @@ namespace TBF.BenchControl.Elde.FlowMeter
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 5; } }
public int MaxCount { get { return 7; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
@@ -0,0 +1,80 @@
using System;
using System.Collections.Generic;
using log4net;
using TBF.Boxes;
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
public class FlowMeter : Generic.IComponent, GenericDevices.IFlowMeter
{
/// <summary>
/// Info: StartMassMeasurement() and "Balance response = .., Mass = ..."
/// Warn: Start measurement when busy is true
/// </summary>
private static readonly ILog log = LogManager.GetLogger(typeof(FlowMeter));
public override string ToString()
{
return string.Format("FlowMeter({0})", Name);
}
public static void ResetStaticProperties() { }
FlowMeterCfg flowMeterCfg;
public Generic.IComponentCfg Cfg { get { return flowMeterCfg; } }
public string Name { get { return flowMeterCfg.Name; } }
public int Idx1 { get { return 0; } }
public IList<Entities.MeasurementCorrection> Corrections { get { return flowMeterCfg.Corrections; } }
public readonly ControlBoardDev ControlBoard;
readonly float nominalFlow;
public float NominalFlow { get { return nominalFlow; } }
public float LtrPerPulse { get { return nominalFlow / 14400.0f; } } /// Assuming the nominal flowed is reached at 4000Hz
public float LtrPerPulseCorrected(float flow)
{
return LtrPerPulse; /// TODO: apply correction
}
public FlowMeter(FlowMeterCfg cfg, IList<Generic.IComponent> components)
{
if (cfg == null) throw new ArgumentNullException("cfg");
this.flowMeterCfg = cfg;
ControlBoard = (ControlBoardDev)TbfComponents.FindComponent(cfg.ParentName, components);
if (ControlBoard == null) throw new Exception("Cannot find " + Name + " parent");
nominalFlow = cfg.NominalFlow;
ControlBoard.EtCalib[Idx1] = NominalFlow;
/// Prepare data for SendCalibData() control board component method
log.Debug(this.ToString());
}
/// <summary>
/// Events: FlowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref FloatBox flow)
{
return new ReadFlowOp(this, ref flow);
}
/// <summary>
/// Events: flowDone, Error
/// </summary>
/// <param name="flow">Reference to a variable for the flow in Bar</param>
/// <param name="flowDone">Event returned when measurement done</param>
/// <returns>ReadFlowOp instance reference casted to IOperaton</returns>
public IOperation ReadFlowOp(ref FloatBox flow, Event flowDone)
{
return new ReadFlowOp(this, ref flow, flowDone);
}
}
}
@@ -0,0 +1,58 @@
using System;
using System.IO;
using System.Xml.Serialization;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
public class FlowMeterCfg : ComponentCfgBase, Generic.IChildComponentCfg
{
public float NominalFlow; /// Nominal flow in m3/h at output frequency 2000 Hz
/// Parameterless constructor
public FlowMeterCfg()
{
}
/// <summary>
/// Flow meter configuration parameters
/// </summary>
/// <param name="name">Flow meter name</param>
/// <param name="parentName">Parent component name</param>
/// <param name="nominalFlow">Nominal flow/param>
public FlowMeterCfg(IComponentFactory factory, string name, string parentName, float nominalFlow)
: base(factory, name, parentName)
{
this.NominalFlow = nominalFlow;
}
public IComponentCfg Clone()
{
return new FlowMeterCfg(Factory, Name, ParentName, NominalFlow);
}
public string ToString(int i)
{
return string.Format("nominalFlow={0}", NominalFlow);
}
public TBF.Entities.Component CreateDbEntity()
{
using (var writer = new StringWriter())
{
(new XmlSerializer(GetType())).Serialize(writer, this);
return Entities.Component.CreateFromCfg(Name, Factory.ClassName, ParentName, ItemNr, DebugLevel, LogLevel, writer.ToString());
}
}
public static IComponentCfg CreateFromDbEntity(Entities.Component component, IComponentFactory factory)
{
using (var reader = new StringReader(component.Parameters))
{
FlowMeterCfg config = (FlowMeterCfg)(new XmlSerializer(typeof(FlowMeterCfg))).Deserialize(reader);
config.InitCfgBaseFromEntity(component, factory);
return config;
}
}
}
}
@@ -0,0 +1,130 @@
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
partial class FlowMeterCfgCtrl
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.parentNameLabel = new System.Windows.Forms.Label();
this.nameTextBox = new System.Windows.Forms.TextBox();
this.nameLabel = new System.Windows.Forms.Label();
this.classNameLabel = new System.Windows.Forms.Label();
this.nominalFlowTextBox = new System.Windows.Forms.TextBox();
this.nominalFlowLabel = new System.Windows.Forms.Label();
this.parentNameComboBox = new System.Windows.Forms.ComboBox();
this.SuspendLayout();
//
// parentNameLabel
//
this.parentNameLabel.AutoSize = true;
this.parentNameLabel.Location = new System.Drawing.Point(30, 90);
this.parentNameLabel.Name = "parentNameLabel";
this.parentNameLabel.Size = new System.Drawing.Size(69, 13);
this.parentNameLabel.TabIndex = 3;
this.parentNameLabel.Text = "Parent Name";
//
// nameTextBox
//
this.nameTextBox.Enabled = false;
this.nameTextBox.Location = new System.Drawing.Point(140, 61);
this.nameTextBox.Name = "nameTextBox";
this.nameTextBox.Size = new System.Drawing.Size(130, 20);
this.nameTextBox.TabIndex = 2;
//
// nameLabel
//
this.nameLabel.AutoSize = true;
this.nameLabel.Location = new System.Drawing.Point(30, 64);
this.nameLabel.Name = "nameLabel";
this.nameLabel.Size = new System.Drawing.Size(35, 13);
this.nameLabel.TabIndex = 1;
this.nameLabel.Text = "Name";
//
// classNameLabel
//
this.classNameLabel.AutoSize = true;
this.classNameLabel.Location = new System.Drawing.Point(137, 37);
this.classNameLabel.Name = "classNameLabel";
this.classNameLabel.Size = new System.Drawing.Size(83, 13);
this.classNameLabel.TabIndex = 0;
this.classNameLabel.Text = "ComonentName";
//
// nominalFlowTextBox
//
this.nominalFlowTextBox.Enabled = false;
this.nominalFlowTextBox.Location = new System.Drawing.Point(224, 138);
this.nominalFlowTextBox.Name = "nominalFlowTextBox";
this.nominalFlowTextBox.Size = new System.Drawing.Size(46, 20);
this.nominalFlowTextBox.TabIndex = 8;
//
// nominalFlowLabel
//
this.nominalFlowLabel.AutoSize = true;
this.nominalFlowLabel.Location = new System.Drawing.Point(30, 141);
this.nominalFlowLabel.Name = "nominalFlowLabel";
this.nominalFlowLabel.Size = new System.Drawing.Size(140, 13);
this.nominalFlowLabel.TabIndex = 7;
this.nominalFlowLabel.Text = "Nominal flow [m3/h @2kHz]";
//
// parentNameComboBox
//
this.parentNameComboBox.Enabled = false;
this.parentNameComboBox.FormattingEnabled = true;
this.parentNameComboBox.Location = new System.Drawing.Point(140, 87);
this.parentNameComboBox.Name = "parentNameComboBox";
this.parentNameComboBox.Size = new System.Drawing.Size(130, 21);
this.parentNameComboBox.TabIndex = 4;
//
// FlowMeterCfgCtrl
//
this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
this.Controls.Add(this.parentNameComboBox);
this.Controls.Add(this.nominalFlowTextBox);
this.Controls.Add(this.nominalFlowLabel);
this.Controls.Add(this.parentNameLabel);
this.Controls.Add(this.nameTextBox);
this.Controls.Add(this.nameLabel);
this.Controls.Add(this.classNameLabel);
this.Name = "FlowMeterCfgCtrl";
this.Size = new System.Drawing.Size(300, 200);
this.Load += new System.EventHandler(this.FlowMeterCfgCtrl_Load);
this.ResumeLayout(false);
this.PerformLayout();
}
#endregion
private System.Windows.Forms.Label parentNameLabel;
private System.Windows.Forms.TextBox nameTextBox;
private System.Windows.Forms.Label nameLabel;
private System.Windows.Forms.Label classNameLabel;
private System.Windows.Forms.TextBox nominalFlowTextBox;
private System.Windows.Forms.Label nominalFlowLabel;
private System.Windows.Forms.ComboBox parentNameComboBox;
}
}
@@ -0,0 +1,93 @@
using System;
using System.Globalization;
using System.Windows.Forms;
using log4net;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
public partial class FlowMeterCfgCtrl : UserControl, IComponentCfgCtrl
{
static readonly ILog log = LogManager.GetLogger(typeof(FlowMeterCfgCtrl));
ComponentParametersDlg parent;
FlowMeterCfg config;
public IComponentCfg Config
{
get { return config as IComponentCfg; }
set
{
config = value as FlowMeterCfg;
Redraw();
}
}
public FlowMeterCfgCtrl()
{
InitializeComponent();
}
private void FlowMeterCfgCtrl_Load(object sender, EventArgs e)
{
parent = ParentForm as ComponentParametersDlg;
if (parent == null) return;
if (parent.TbfComponents != null)
{
foreach (var cmpnt in parent.TbfComponents)
{
if (TbfComponents.CmpntFactoryFromClassName(cmpnt.ClassName) is Elde.ControlBoardFactory)
{
parentNameComboBox.Items.Add(cmpnt.Name);
}
}
}
Redraw();
}
void Redraw()
{
if (config == null) return; /// Control was not loaded, settings were not changed
classNameLabel.Text = config.Factory.ClassName;
nameTextBox.Text = config.Name;
parentNameComboBox.Text = string.IsNullOrEmpty(config.ParentName) ? "---" : config.ParentName;
nominalFlowTextBox.Text = config.NominalFlow.ToString();
}
public void Unlock()
{
nameTextBox.Enabled = true;
parentNameComboBox.Enabled = true;
nominalFlowTextBox.Enabled = true;
}
public CfgVerifyFlags VerifyCfg(ref string message)
{
CfgVerifyFlags flags = CfgVerifyFlags.None;
if (!parentNameComboBox.Items.Contains(parentNameComboBox.Text))
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "Invalid 'Parent Name'";
}
float fdummy;
if (!Utils.TryParseUFloat(nominalFlowTextBox.Text, out fdummy) || fdummy < 0.2 || fdummy > 1600)
{
flags |= CfgVerifyFlags.Error;
message += Environment.NewLine + "'Nominal flow' should be between 0.2 and 1600";
}
return flags;
}
public void UpdateCfg()
{
if (config == null) return; /// Control was not loaded, settings were not changed
config.Name = nameTextBox.Text;
config.ParentName = parentNameComboBox.Text.Equals("---") ? string.Empty : parentNameComboBox.Text;
Utils.TryParseUFloat(nominalFlowTextBox.Text, out config.NominalFlow);
}
}
}
@@ -0,0 +1,120 @@
<?xml version="1.0" encoding="utf-8"?>
<root>
<!--
Microsoft ResX Schema
Version 2.0
The primary goals of this format is to allow a simple XML format
that is mostly human readable. The generation and parsing of the
various data types are done through the TypeConverter classes
associated with the data types.
Example:
... ado.net/XML headers & schema ...
<resheader name="resmimetype">text/microsoft-resx</resheader>
<resheader name="version">2.0</resheader>
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
<value>[base64 mime encoded serialized .NET Framework object]</value>
</data>
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
<comment>This is a comment</comment>
</data>
There are any number of "resheader" rows that contain simple
name/value pairs.
Each data row contains a name, and value. The row also contains a
type or mimetype. Type corresponds to a .NET class that support
text/value conversion through the TypeConverter architecture.
Classes that don't support this are serialized and stored with the
mimetype set.
The mimetype is used for serialized objects, and tells the
ResXResourceReader how to depersist the object. This is currently not
extensible. For a given mimetype the value must be set accordingly:
Note - application/x-microsoft.net.object.binary.base64 is the format
that the ResXResourceWriter will generate, however the reader can
read any of the formats listed below.
mimetype: application/x-microsoft.net.object.binary.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.soap.base64
value : The object must be serialized with
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
: and then encoded with base64 encoding.
mimetype: application/x-microsoft.net.object.bytearray.base64
value : The object must be serialized into a byte array
: using a System.ComponentModel.TypeConverter
: and then encoded with base64 encoding.
-->
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
<xsd:element name="root" msdata:IsDataSet="true">
<xsd:complexType>
<xsd:choice maxOccurs="unbounded">
<xsd:element name="metadata">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" />
</xsd:sequence>
<xsd:attribute name="name" use="required" type="xsd:string" />
<xsd:attribute name="type" type="xsd:string" />
<xsd:attribute name="mimetype" type="xsd:string" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="assembly">
<xsd:complexType>
<xsd:attribute name="alias" type="xsd:string" />
<xsd:attribute name="name" type="xsd:string" />
</xsd:complexType>
</xsd:element>
<xsd:element name="data">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
<xsd:attribute ref="xml:space" />
</xsd:complexType>
</xsd:element>
<xsd:element name="resheader">
<xsd:complexType>
<xsd:sequence>
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
</xsd:sequence>
<xsd:attribute name="name" type="xsd:string" use="required" />
</xsd:complexType>
</xsd:element>
</xsd:choice>
</xsd:complexType>
</xsd:element>
</xsd:schema>
<resheader name="resmimetype">
<value>text/microsoft-resx</value>
</resheader>
<resheader name="version">
<value>2.0</value>
</resheader>
<resheader name="reader">
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
<resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader>
</root>
@@ -0,0 +1,43 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using TBF.BenchControl.Generic;
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
public class FlowMeterFactory : IComponentFactory
{
public string ClassName { get { return "FlowMeterCouple"; } }
public bool HasProcedureParams { get { return false; } }
public bool HasTestParams { get { return false; } }
public IParamsProvider GetTestParams(Entities.ComponentTest testParams) { return null; }
public IParamsProvider GetProcedureParams(Entities.ComponentProcedure procedureParams) { return null; }
/// <summary>Max. number of components of this class in the system</summary>
public int MaxCount { get { return 1; } }
public IComponentCfg DefaultConfig(IList<Entities.Component> components)
{
return new FlowMeterCfg(this, "FlowMeterCouple", "CB", 1600);
}
public IComponentCfgCtrl CreateCfgCtrl()
{
return new FlowMeterCfgCtrl();
}
public IComponent ComponentFromCmpntCfg(IComponentCfg config, IList<Generic.IComponent> components)
{
return new FlowMeter((FlowMeterCfg)config, components);
}
public IComponentCfg CmpntCfgFromCmpntEntity(Entities.Component component)
{
return FlowMeterCfg.CreateFromDbEntity(component, this);
}
public void ResetStaticProperties() { FlowMeter.ResetStaticProperties(); }
}
}
@@ -0,0 +1,66 @@
using System;
using log4net;
using TBF.Boxes;
namespace TBF.BenchControl.Elde.FlowMeterCouple
{
public class ReadFlowOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(ReadFlowOp));
public override string ToString() { return string.Format("ReadFlowOp(.,{0},{1},.)", eventDone, flowMeterNr); }
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly int flowMeterNr;
readonly Event eventDone;
FloatBox flow;
/// <summary>
/// Events: FlowInDone, FlowOutDone or Error
/// </summary>
/// <param name="flowMeter">Flow meter reference</param>
/// <param name="flow">Reference to the measured flow variable, value is in bar</param>
/// <param name="eventDone">Event to be returned by Run() when completed OK</param>
public ReadFlowOp(FlowMeter flowMeter, ref FloatBox flow, Event eventDone)
{
if (flowMeter == null) throw new ArgumentNullException("flowMeter");
this.controlBoard = flowMeter.ControlBoard;
this.flowMeterNr = flowMeter.Idx1;
this.eventDone = eventDone;
this.flow = flow;
log.Debug(this.ToString());
}
public ReadFlowOp(FlowMeter flowMeter, ref FloatBox flow)
: this(flowMeter, ref flow, Event.FlowMeasurementDone)
{
}
/// <summary>Start this operation</summary>
public void Start()
{
}
/// <summary>Run this operation</summary>
/// <returns>
/// Event.FlowInDone or Event.FlowOutDone
/// </returns>
public Event Run()
{
if (flowMeterNr == (int)(controlBoard.StatusP & StatusP.RefFlowMeterMask))
{
flow.Val = controlBoard.ReferenceFlow;
return eventDone;
}
else
{
return Event.Error;
}
}
/// <summary>Stop this operation</summary>
public void Stop()
{
}
}
}
@@ -16,7 +16,6 @@ namespace TBF.BenchControl.Elde.RegulValve
/// Set by the constructor
readonly ControlBoardDev controlBoard;
readonly Elde.FlowMeter.FlowMeter flowMeter;
readonly Elde.RegulValve.RegulValve regulValve;
readonly int regulValveNr;
readonly int flowMeterNr;
@@ -26,6 +25,8 @@ namespace TBF.BenchControl.Elde.RegulValve
readonly int timeout;
readonly bool leaveMeasurementRunning;
readonly float nominalFlow;
/// Process values
enum OpState
{
@@ -68,9 +69,20 @@ namespace TBF.BenchControl.Elde.RegulValve
if (regulValve == null) throw new ArgumentNullException("regValve is null or not Elde");
this.regulValveNr = this.regulValve.Idx1;
this.flowMeter = flowMeter as Elde.FlowMeter.FlowMeter;
if (flowMeter == null) throw new ArgumentNullException("flowMeter in null or not Elde");
this.flowMeterNr = this.flowMeter.Idx1;
if (flowMeter is Elde.FlowMeter.FlowMeter)
{
this.flowMeterNr = (flowMeter as Elde.FlowMeter.FlowMeter).Idx1;
}
else if (flowMeter is Elde.FlowMeterCouple.FlowMeter)
{
this.flowMeterNr = 0;
}
else
{
throw new ArgumentNullException("flowMeter is null or not Elde");
}
nominalFlow = flowMeter.NominalFlow;
this.reqFlowLo = requiredFlowLo;
this.reqFlowHi = requiredFlowHi;
@@ -174,7 +186,7 @@ namespace TBF.BenchControl.Elde.RegulValve
{
float rvPosition = controlBoard.RValvePosition(regulValveNr);
float flowMtrFreq = controlBoard.ReferenceFreq;
float flow = flowMtrFreq * flowMeter.NominalFlow / 2000.0f;
float flow = flowMtrFreq * nominalFlow / 2000.0f;
if (measuredFlow != null) measuredFlow.Val = flow;
@@ -200,7 +212,7 @@ namespace TBF.BenchControl.Elde.RegulValve
}
else if (opState == OpState.ValveMoveToFlow)
{
if (reqFlowLo >= reqFlowHi || reqFlowLo > flowMeter.NominalFlow || reqFlowHi <= 0)
if (reqFlowLo >= reqFlowHi || reqFlowLo > nominalFlow || reqFlowHi <= 0)
{
return Event.OpArgumentError;
}
@@ -208,8 +220,8 @@ namespace TBF.BenchControl.Elde.RegulValve
log.InfoFormat("Run(): rv#={0} flowMtr#={1} TARGET: flowLo={2} flowHi={3}",
regulValveNr, flowMeterNr, reqFlowLo, reqFlowHi);
float freqLo = 2000.0f * reqFlowLo / flowMeter.NominalFlow;
float freqHi = 2000.0f * reqFlowHi / flowMeter.NominalFlow;
float freqLo = 2000.0f * reqFlowLo / nominalFlow;
float freqHi = 2000.0f * reqFlowHi / nominalFlow;
controlBoard.ValveMove(regulValveNr, RegulValveMode.TargetFrequency,
new float[2] { freqLo, freqHi },
regulValve.StableTime);
@@ -10,10 +10,22 @@ namespace TBF.BenchControl.GenericDevices
public interface IFlowMeter : IComponent
{
/// <summary>
/// Nominal flow @2kHz output frequency in m3
/// Nominal flow in m3/h at the maximum (2kHz) output frequency.
/// In case of a flowmeter couple, the sum of two nominal flows (reached at 4kHz of summed pulses).
/// </summary>
float NominalFlow { get; }
/// <summary>
/// Nominal (uncorrected) volume per flowmeter pulse in [l].
/// </summary>
float LtrPerPulse { get; }
/// <summary>
/// Corrected volume per flowmeter pulse in [l].
/// </summary>
/// <param name="flow">Water flow in [m3/h]</param>
float LtrPerPulseCorrected(float flow);
/// <summary>
/// 1 based index of the reference flowmeter
/// </summary>
@@ -19,6 +19,7 @@ namespace TBF.BenchControl
Factories.Add(new Elde.ControlBoardFactory());
Factories.Add(new Elde.Diverter.DiverterFactory());
Factories.Add(new Elde.FlowMeter.FlowMeterFactory());
Factories.Add(new Elde.FlowMeterCouple.FlowMeterFactory());
Factories.Add(new Elde.PressureMeter.PressureMeterFactory());
Factories.Add(new Elde.Pump.PumpFactory());
Factories.Add(new Elde.PumpWithFM.PumpFactory());
@@ -35,17 +35,17 @@ namespace TBF.BenchControl.TestMethods.FlyingStartCollectionMethod
IList<Event> e; /// Events from currently running operations
Event retVal = Event.Done;
ltrPerRefPulse = outPath.FlowMeter.LtrPerPulse; /// [ltr/pulse], nominal flow in [m3/h]
/// Notes:
/// float timeHr = volumeLtr / (1000.0f * targetFlow);
/// float timeSec = 3600.0f * timeHr;
/// int refPulses = (int)(timeSec * (2000.0f * targetFlow / pOut.FlowMeter.NominalFlow));
int totalPulses = (int)(7200.0f * test.Volume / outPath.FlowMeter.NominalFlow); /// Nominal flow in [m3/h]
int totalPulses = (int)(test.Volume / ltrPerRefPulse);
/// Double total pulses for 'added' flowmeters
if (outPath.FlowMeter.Cfg.Name.Contains("+")) { totalPulses *= 2; }
ltrPerRefPulse = outPath.FlowMeter.NominalFlow / 7200.0f; /// [ltr/pulse]
///
processDataLoggingOp = new TBF.BenchControl.Operations.ProcessDataLoggingOp(processDataLogger, this);
int repetitionNr = 1; /// First test: repetitionNr=1
+13
View File
@@ -203,6 +203,16 @@
<DependentUpon>EntryFormCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="BenchControl\DataEntry\Munich\EntryFormFactory.cs" />
<Compile Include="BenchControl\Elde\FlowMeterCouple\FlowMeter.cs" />
<Compile Include="BenchControl\Elde\FlowMeterCouple\FlowMeterCfg.cs" />
<Compile Include="BenchControl\Elde\FlowMeterCouple\FlowMeterCfgCtrl.cs">
<SubType>UserControl</SubType>
</Compile>
<Compile Include="BenchControl\Elde\FlowMeterCouple\FlowMeterCfgCtrl.designer.cs">
<DependentUpon>FlowMeterCfgCtrl.cs</DependentUpon>
</Compile>
<Compile Include="BenchControl\Elde\FlowMeterCouple\FlowMeterFactory.cs" />
<Compile Include="BenchControl\Elde\FlowMeterCouple\ReadFlowOp.cs" />
<Compile Include="BenchControl\Elde\PumpWithFM\FMPumpTestParams.cs" />
<Compile Include="BenchControl\Elde\PumpWithFM\Pump.cs" />
<Compile Include="BenchControl\Elde\PumpWithFM\PumpCfg.cs" />
@@ -915,6 +925,9 @@
<EmbeddedResource Include="BenchControl\Elde\Diverter\DiverterCfgCtrl.resx">
<DependentUpon>DiverterCfgCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="BenchControl\Elde\FlowMeterCouple\FlowMeterCfgCtrl.resx">
<DependentUpon>FlowMeterCfgCtrl.cs</DependentUpon>
</EmbeddedResource>
<EmbeddedResource Include="BenchControl\Elde\FlowMeter\FlowMeterCfgCtrl.resx">
<DependentUpon>FlowMeterCfgCtrl.cs</DependentUpon>
</EmbeddedResource>