MiniPrf: - adapted to static methods in FM2014

This commit is contained in:
Thomas Wiedebusch 2026-02-11 17:16:23 +01:00
parent 26e1ea6378
commit 91fa956e41
4 changed files with 531 additions and 461 deletions

View File

@ -503,7 +503,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
public UInt16 DutPulses_per_cm
{
get => _dutPulses_per_cm;
private set
set
{
// Check limits and equality, the DUT max input is 9999 as this will be
// directly stored to FM2014'V' - 'DUT pulses per volume'
@ -876,6 +876,18 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
if (firstActiveFm2014 == null)
return false;
// Publish setting to all connected and logged in FM2014s as those will be delivered
// for all via broadcast
foreach (var fm2014 in RegisteredFm2014s.Where(fm2014 => fm2014.IsLoggedOn))
{
fm2014.RefPulseCtrOn = refPulseCtrOn;
fm2014.DutPulseCtrOn = dutPulseCtrOn;
// Remove the measurement ready lock used for cyclic request
fm2014.MeasurementIsReady = false;
// Remove error marker
fm2014.ErrorIsDetected = false;
}
// Check if any pulse counter is required
if (!firstActiveFm2014.RefPulseCtrOn && !firstActiveFm2014.DutPulseCtrOn)
{
@ -1573,7 +1585,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core
// Check all remaining DUT and REF pulses are counted on all connected devices and finalize process by
// reading out all results
//TODO THW rework to take timeout for unresponsive device into account
//TODO THW take timeout for unresponsive device into account and if REF and/or DUT
if (RegisteredFm2014s.All(fm2014 => fm2014.RefPulsesRemaining == 0 &&
fm2014.DutPulsesRemaining == 0))
{

View File

@ -865,10 +865,14 @@ namespace Sensus.Ui.FM2014TestBench
tbxScaleRefToDut.Background = ColorProcessFailed;
tbxScaleRefToDut.Text = Properties.Resources.StrError;
btnSaveRegulationSetup.IsEnabled = false;
btnDutToRefRegulation.IsEnabled = false;
});
return false;
}
Dispatcher.Invoke(() =>
{
tbxScaleRefToDut.Background = ColorStandardDisplayField;
});
return true;
}
@ -1137,6 +1141,7 @@ namespace Sensus.Ui.FM2014TestBench
break;
case CmdName.CMD_DUT_GET_PLS_CTR:
case CmdName.CMD_DUT_GET_PLS_CTR_BU:
if (firstFm2014 != null && firstFm2014.Address == fm2014.Address)
UpdateTextBox(tbxDutPulsesMeasured, $"{resp.IntValue:D}");
ucFm2014.SetValue(CTR_LBL_IDX_DUT_PLS, $"{resp.IntValue:D}");
break;
@ -1262,10 +1267,6 @@ namespace Sensus.Ui.FM2014TestBench
foreach (var measLbl in MeasurementLabels)
UiElmEnable(measLbl, false, false);
// Backup if meanwhile anything has changed
if (_configSetupHasChanged || _calibrationSetupHasChanged)
StoreFM2014SettingsToConfigFile();
// Set the measurement labels
UpdateContentControl(MeasurementLabels[CAL_LBL_IDX_REF_REQ_PLS], Properties.Resources.StrLblRefPulsesRequired);
UpdateContentControl(MeasurementLabels[CAL_LBL_IDX_REF_RMN_PLS], Properties.Resources.StrLblRefPulsesRemaining);
@ -1289,8 +1290,8 @@ namespace Sensus.Ui.FM2014TestBench
UInt16? refPulsesRequired = null;
UInt16? dutPulsesRequired = null;
UInt16 doublePulseDeadtime_ms = 0;
Double tolerenceThresholdMax_percent = 1.0;
Double tolerenceThresholdMin_percent = -0.7;
Double toleranceThresholdMax_percent = 1.0;
Double toleranceThresholdMin_percent = -0.7;
Dispatcher.Invoke(() =>
{
if (int.TryParse(tbxRefPulsesRequired.Text, out var pulses) &&
@ -1315,12 +1316,12 @@ namespace Sensus.Ui.FM2014TestBench
var englishNumberFormat = tbxDutToRefTolMax.Text.Replace(',', '.');
if (double.TryParse(englishNumberFormat, NumberStyles.Any, new CultureInfo("en"), out var tolerance))
{
tolerenceThresholdMax_percent = tolerance;
toleranceThresholdMax_percent = tolerance;
}
englishNumberFormat = tbxDutToRefTolMin.Text.Replace(',', '.');
if (double.TryParse(englishNumberFormat, NumberStyles.Any, new CultureInfo("en"), out tolerance))
{
tolerenceThresholdMin_percent = tolerance;
toleranceThresholdMin_percent = tolerance;
}
});
@ -1336,12 +1337,16 @@ namespace Sensus.Ui.FM2014TestBench
ucFM2014.SetValue(CAL_LBL_IDX_DUT_REQ_PLS, dutPulsesRequired != null ? $"{dutPulsesRequired}" : "---");
// Set thresholds for tolerance verification
fm2014.DutToRefCalibrationToleranceMax_percent = tolerenceThresholdMax_percent;
fm2014.DutToRefCalibrationToleranceMin_percent = tolerenceThresholdMin_percent;
fm2014.DutToRefCalibrationToleranceMax_percent = toleranceThresholdMax_percent;
fm2014.DutToRefCalibrationToleranceMin_percent = toleranceThresholdMin_percent;
}
if (FM2014.PulseTimeMeasurement(refPulsesRequired, dutPulsesRequired, doublePulseDeadtime_ms))
{
// Backup if meanwhile anything has changed
if (_configSetupHasChanged || _calibrationSetupHasChanged)
StoreFM2014SettingsToConfigFile();
_autoProgressBar = false;
ActionControl(true);
UpdateContentControl(btnDutToRefCalibration, Properties.Resources.StrBtnStopCalibration);
@ -1388,6 +1393,7 @@ namespace Sensus.Ui.FM2014TestBench
UInt16 dutPulses_per_cm = 100;
UInt16 doublePulseDeadtime_ms = 0;
Byte currentOutputAttenuation = 1;
Int32 toleranceSetup = 1;
Dispatcher.Invoke(() =>
{
if (int.TryParse(tbxRefPulsesPerCm.Text, out var pulses_per_cm) &&
@ -1416,6 +1422,13 @@ namespace Sensus.Ui.FM2014TestBench
{
currentOutputAttenuation = attenuation;
}
if (int.TryParse(cbxToleranceCalc.SelectedItem.ToString(), out var tolerance) &&
(tolerance == FM2014.STANDARD_NOMINAL_TOLERANCE_INPUT_percent ||
tolerance == FM2014.EXTENDED_NOMINAL_TOLERANCE_INPUT_percent))
{
toleranceSetup = tolerance;
}
});
// Adjust the user control
@ -1424,6 +1437,7 @@ namespace Sensus.Ui.FM2014TestBench
var idx = fm2014.Address - 1;
var ucFM2014 = (UcFM2014Device)UcFM2014s[idx];
ucFM2014.EnableMeasurements(REG_MEASURE_COUNT);
fm2014.Tolerance_percent = toleranceSetup;
}
if (FM2014.RegulationMeasurement(refPulses_per_cm, dutPulses_per_cm, doublePulseDeadtime_ms,
@ -1482,8 +1496,8 @@ namespace Sensus.Ui.FM2014TestBench
var idx = fm2014.Address - 1;
var ucFM2014 = (UcFM2014Device)UcFM2014s[idx];
ucFM2014.EnableMeasurements(CTR_MEASURE_COUNT);
fm2014.RefPulseCtrOn = true;
fm2014.DutPulseCtrOn = measureDutPulses;
//fm2014.RefPulseCtrOn = true;
//fm2014.DutPulseCtrOn = measureDutPulses;
}
if (FM2014.PulseCounterMeasurement(true, measureDutPulses))
@ -1541,12 +1555,6 @@ namespace Sensus.Ui.FM2014TestBench
tolerance == FM2014.EXTENDED_NOMINAL_TOLERANCE_INPUT_percent) &&
firstFm2014.Tolerance_percent != tolerance)
{
firstFm2014.Tolerance_percent = tolerance;
// Dispatch settings to all connected FM2014
foreach (var fm2014 in FM2014.RegisteredFm2014s)
{
fm2014.Tolerance_percent = tolerance;
}
_regulationSetupHasChanged = true;
btnSaveRegulationSetup.IsEnabled = true;
}
@ -2231,8 +2239,6 @@ namespace Sensus.Ui.FM2014TestBench
if (string.IsNullOrEmpty(tbxRefPulsesPerCm.Text))
{
tbxRefPulsesPerCm.Background = ColorProcessFailed;
tbxDutPulsesPerCm.Background = ColorProcessFailed;
tbxScaleRefToDut.Background = ColorProcessFailed;
btnSaveRegulationSetup.IsEnabled = false;
btnDutToRefRegulation.IsEnabled = false;
return;
@ -2247,6 +2253,11 @@ namespace Sensus.Ui.FM2014TestBench
FM2014.REF_PULSES_PER_CM_REGULATION_INPUT_MAX >= pulses_per_cm)
{
// During setup of the 'Ref_pulse_per_cm' the 'RefToDutScaleStr' will be generated
foreach (var fm2014 in FM2014.RegisteredFm2014s)
{
fm2014.RefPulses_per_cm = (UInt32)pulses_per_cm;
}
if (!UpdateRefToDutScale())
{
tbxRefPulsesPerCm.Background = ColorProcessFailed;
@ -2327,9 +2338,7 @@ namespace Sensus.Ui.FM2014TestBench
{
if (string.IsNullOrEmpty(tbxDutPulsesPerCm.Text))
{
tbxRefPulsesPerCm.Background = ColorProcessFailed;
tbxDutPulsesPerCm.Background = ColorProcessFailed;
tbxScaleRefToDut.Background = ColorProcessFailed;
btnSaveRegulationSetup.IsEnabled = false;
btnDutToRefRegulation.IsEnabled = false;
return;
@ -2344,6 +2353,11 @@ namespace Sensus.Ui.FM2014TestBench
FM2014.PULSES_PER_CM_REGULATION_SETUP_MAX >= pulses_per_cm)
{
// During setup of the 'Dut_pulse_per_cm' the 'RefToDutScaleStr' will be generated
foreach (var fm2014 in FM2014.RegisteredFm2014s)
{
fm2014.DutPulses_per_cm = (UInt16)pulses_per_cm;
}
if (!UpdateRefToDutScale())
{
tbxDutPulsesPerCm.Background = ColorProcessFailed;

View File

@ -52,8 +52,8 @@
this.lblDutPulsePerVolume = new System.Windows.Forms.Label();
this.lblAttenuation = new System.Windows.Forms.Label();
this.lblScaleRefToDut = new System.Windows.Forms.Label();
this.tbxRefPulsePerCm = new System.Windows.Forms.TextBox();
this.tbxDutPulsePerCm = new System.Windows.Forms.TextBox();
this.tbxRefPulsesPerCm = new System.Windows.Forms.TextBox();
this.tbxDutPulsesPerCm = new System.Windows.Forms.TextBox();
this.tbxScaleRefToDut = new System.Windows.Forms.TextBox();
this.lblUpdateTimeValue = new System.Windows.Forms.Label();
this.tmrProgressUpdate = new System.Windows.Forms.Timer(this.components);
@ -64,13 +64,13 @@
this.btnDutToRefRegulation = new System.Windows.Forms.Button();
this.gbxManualRefCalibration = new System.Windows.Forms.GroupBox();
this.cbxMeasuredDutPulses = new System.Windows.Forms.CheckBox();
this.tbxMeasuredDutPulses = new System.Windows.Forms.TextBox();
this.tbxDutPulsesMeasured = new System.Windows.Forms.TextBox();
this.lblPulseVolumeCmRelation = new System.Windows.Forms.Label();
this.tbxRefCalibrationResultPulsePerCm = new System.Windows.Forms.TextBox();
this.lblWeightScaleVolume = new System.Windows.Forms.Label();
this.tbxManualInputVolumeLiters = new System.Windows.Forms.TextBox();
this.tbxVolumeMeasuredLiters = new System.Windows.Forms.TextBox();
this.lblMeasuredRefPulses = new System.Windows.Forms.Label();
this.tbxMeasuredRefPulses = new System.Windows.Forms.TextBox();
this.tbxRefPulsesMeasured = new System.Windows.Forms.TextBox();
this.btnManualRefCalibration = new System.Windows.Forms.Button();
this.gbxDutToRefRegulation = new System.Windows.Forms.GroupBox();
this.lblRefFrequencyHz = new System.Windows.Forms.Label();
@ -292,8 +292,8 @@
this.gbxRegulationSetup.Controls.Add(this.lblDutPulsePerVolume);
this.gbxRegulationSetup.Controls.Add(this.lblAttenuation);
this.gbxRegulationSetup.Controls.Add(this.lblScaleRefToDut);
this.gbxRegulationSetup.Controls.Add(this.tbxRefPulsePerCm);
this.gbxRegulationSetup.Controls.Add(this.tbxDutPulsePerCm);
this.gbxRegulationSetup.Controls.Add(this.tbxRefPulsesPerCm);
this.gbxRegulationSetup.Controls.Add(this.tbxDutPulsesPerCm);
this.gbxRegulationSetup.Controls.Add(this.tbxScaleRefToDut);
this.gbxRegulationSetup.Location = new System.Drawing.Point(8, 239);
this.gbxRegulationSetup.Name = "gbxRegulationSetup";
@ -369,25 +369,25 @@
this.lblScaleRefToDut.TabIndex = 64;
this.lblScaleRefToDut.Text = "REF/DUT Scale [norm]";
//
// tbxRefPulsePerCm
// tbxRefPulsesPerCm
//
this.tbxRefPulsePerCm.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxRefPulsePerCm.Location = new System.Drawing.Point(220, 26);
this.tbxRefPulsePerCm.Name = "tbxRefPulsePerCm";
this.tbxRefPulsePerCm.Size = new System.Drawing.Size(60, 20);
this.tbxRefPulsePerCm.TabIndex = 4;
this.tbxRefPulsePerCm.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxRefPulsesPerCm_KeyDown);
this.tbxRefPulsePerCm.Leave += new System.EventHandler(this.tbxRefPulsesPerCm_Leave);
this.tbxRefPulsesPerCm.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxRefPulsesPerCm.Location = new System.Drawing.Point(220, 26);
this.tbxRefPulsesPerCm.Name = "tbxRefPulsesPerCm";
this.tbxRefPulsesPerCm.Size = new System.Drawing.Size(60, 20);
this.tbxRefPulsesPerCm.TabIndex = 4;
this.tbxRefPulsesPerCm.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxRefPulsesPerCm_KeyDown);
this.tbxRefPulsesPerCm.Leave += new System.EventHandler(this.tbxRefPulsesPerCm_Leave);
//
// tbxDutPulsePerCm
// tbxDutPulsesPerCm
//
this.tbxDutPulsePerCm.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxDutPulsePerCm.Location = new System.Drawing.Point(220, 51);
this.tbxDutPulsePerCm.Name = "tbxDutPulsePerCm";
this.tbxDutPulsePerCm.Size = new System.Drawing.Size(60, 20);
this.tbxDutPulsePerCm.TabIndex = 5;
this.tbxDutPulsePerCm.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxDutPulsesPerCm_KeyDown);
this.tbxDutPulsePerCm.Leave += new System.EventHandler(this.tbxDutPulsesPerCm_Leave);
this.tbxDutPulsesPerCm.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxDutPulsesPerCm.Location = new System.Drawing.Point(220, 51);
this.tbxDutPulsesPerCm.Name = "tbxDutPulsesPerCm";
this.tbxDutPulsesPerCm.Size = new System.Drawing.Size(60, 20);
this.tbxDutPulsesPerCm.TabIndex = 5;
this.tbxDutPulsesPerCm.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxDutPulsesPerCm_KeyDown);
this.tbxDutPulsesPerCm.Leave += new System.EventHandler(this.tbxDutPulsesPerCm_Leave);
//
// tbxScaleRefToDut
//
@ -461,13 +461,13 @@
// gbxManualRefCalibration
//
this.gbxManualRefCalibration.Controls.Add(this.cbxMeasuredDutPulses);
this.gbxManualRefCalibration.Controls.Add(this.tbxMeasuredDutPulses);
this.gbxManualRefCalibration.Controls.Add(this.tbxDutPulsesMeasured);
this.gbxManualRefCalibration.Controls.Add(this.lblPulseVolumeCmRelation);
this.gbxManualRefCalibration.Controls.Add(this.tbxRefCalibrationResultPulsePerCm);
this.gbxManualRefCalibration.Controls.Add(this.lblWeightScaleVolume);
this.gbxManualRefCalibration.Controls.Add(this.tbxManualInputVolumeLiters);
this.gbxManualRefCalibration.Controls.Add(this.tbxVolumeMeasuredLiters);
this.gbxManualRefCalibration.Controls.Add(this.lblMeasuredRefPulses);
this.gbxManualRefCalibration.Controls.Add(this.tbxMeasuredRefPulses);
this.gbxManualRefCalibration.Controls.Add(this.tbxRefPulsesMeasured);
this.gbxManualRefCalibration.Controls.Add(this.btnManualRefCalibration);
this.gbxManualRefCalibration.Location = new System.Drawing.Point(302, 75);
this.gbxManualRefCalibration.Name = "gbxManualRefCalibration";
@ -486,14 +486,14 @@
this.cbxMeasuredDutPulses.Text = "Measured DUT [Pulses]:";
this.cbxMeasuredDutPulses.UseVisualStyleBackColor = true;
//
// tbxMeasuredDutPulses
// tbxDutPulsesMeasured
//
this.tbxMeasuredDutPulses.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxMeasuredDutPulses.Location = new System.Drawing.Point(164, 51);
this.tbxMeasuredDutPulses.Name = "tbxMeasuredDutPulses";
this.tbxMeasuredDutPulses.ReadOnly = true;
this.tbxMeasuredDutPulses.Size = new System.Drawing.Size(60, 20);
this.tbxMeasuredDutPulses.TabIndex = 75;
this.tbxDutPulsesMeasured.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxDutPulsesMeasured.Location = new System.Drawing.Point(164, 51);
this.tbxDutPulsesMeasured.Name = "tbxDutPulsesMeasured";
this.tbxDutPulsesMeasured.ReadOnly = true;
this.tbxDutPulsesMeasured.Size = new System.Drawing.Size(60, 20);
this.tbxDutPulsesMeasured.TabIndex = 75;
//
// lblPulseVolumeCmRelation
//
@ -522,15 +522,15 @@
this.lblWeightScaleVolume.TabIndex = 70;
this.lblWeightScaleVolume.Text = "Volume [liters]:";
//
// tbxManualInputVolumeLiters
// tbxVolumeMeasuredLiters
//
this.tbxManualInputVolumeLiters.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxManualInputVolumeLiters.Location = new System.Drawing.Point(164, 77);
this.tbxManualInputVolumeLiters.Name = "tbxManualInputVolumeLiters";
this.tbxManualInputVolumeLiters.Size = new System.Drawing.Size(60, 20);
this.tbxManualInputVolumeLiters.TabIndex = 8;
this.tbxManualInputVolumeLiters.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxManualInputVolumeLiters_KeyStoke);
this.tbxManualInputVolumeLiters.Leave += new System.EventHandler(this.tbxManualInputVolumeLiters_Leave);
this.tbxVolumeMeasuredLiters.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxVolumeMeasuredLiters.Location = new System.Drawing.Point(164, 77);
this.tbxVolumeMeasuredLiters.Name = "tbxVolumeMeasuredLiters";
this.tbxVolumeMeasuredLiters.Size = new System.Drawing.Size(60, 20);
this.tbxVolumeMeasuredLiters.TabIndex = 8;
this.tbxVolumeMeasuredLiters.KeyDown += new System.Windows.Forms.KeyEventHandler(this.tbxManualInputVolumeLiters_KeyStoke);
this.tbxVolumeMeasuredLiters.Leave += new System.EventHandler(this.tbxManualInputVolumeLiters_Leave);
//
// lblMeasuredRefPulses
//
@ -541,14 +541,14 @@
this.lblMeasuredRefPulses.TabIndex = 68;
this.lblMeasuredRefPulses.Text = "Measured REF [Pulses]:";
//
// tbxMeasuredRefPulses
// tbxRefPulsesMeasured
//
this.tbxMeasuredRefPulses.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxMeasuredRefPulses.Location = new System.Drawing.Point(164, 26);
this.tbxMeasuredRefPulses.Name = "tbxMeasuredRefPulses";
this.tbxMeasuredRefPulses.ReadOnly = true;
this.tbxMeasuredRefPulses.Size = new System.Drawing.Size(60, 20);
this.tbxMeasuredRefPulses.TabIndex = 69;
this.tbxRefPulsesMeasured.BorderStyle = System.Windows.Forms.BorderStyle.FixedSingle;
this.tbxRefPulsesMeasured.Location = new System.Drawing.Point(164, 26);
this.tbxRefPulsesMeasured.Name = "tbxRefPulsesMeasured";
this.tbxRefPulsesMeasured.ReadOnly = true;
this.tbxRefPulsesMeasured.Size = new System.Drawing.Size(60, 20);
this.tbxRefPulsesMeasured.TabIndex = 69;
//
// btnManualRefCalibration
//
@ -877,8 +877,8 @@
private System.Windows.Forms.Label lblDutPulsePerVolume;
private System.Windows.Forms.Label lblAttenuation;
private System.Windows.Forms.Label lblScaleRefToDut;
private System.Windows.Forms.TextBox tbxRefPulsePerCm;
private System.Windows.Forms.TextBox tbxDutPulsePerCm;
private System.Windows.Forms.TextBox tbxRefPulsesPerCm;
private System.Windows.Forms.TextBox tbxDutPulsesPerCm;
private System.Windows.Forms.TextBox tbxScaleRefToDut;
private System.Windows.Forms.Label lblUpdateTimeValue;
private System.Windows.Forms.Timer tmrProgressUpdate;
@ -899,11 +899,11 @@
private System.Windows.Forms.GroupBox gbxManualRefCalibration;
private System.Windows.Forms.GroupBox gbxDutToRefRegulation;
private System.Windows.Forms.Button btnManualRefCalibration;
private System.Windows.Forms.TextBox tbxMeasuredRefPulses;
private System.Windows.Forms.TextBox tbxRefPulsesMeasured;
private System.Windows.Forms.Label lblPulseVolumeCmRelation;
private System.Windows.Forms.TextBox tbxRefCalibrationResultPulsePerCm;
private System.Windows.Forms.Label lblWeightScaleVolume;
private System.Windows.Forms.TextBox tbxManualInputVolumeLiters;
private System.Windows.Forms.TextBox tbxVolumeMeasuredLiters;
private System.Windows.Forms.Label lblActualMeasuredTolerance;
private System.Windows.Forms.TextBox tbxActualMeasuredToleranceDutToRef;
private System.Windows.Forms.Label lblActualFlowRateCmPerHour;
@ -931,7 +931,7 @@
private System.Windows.Forms.Label label7;
private System.Windows.Forms.TextBox tbxRefFlowRateFromRefFrequencyCmPerH;
private System.Windows.Forms.MenuStrip menuStrip1;
private System.Windows.Forms.TextBox tbxMeasuredDutPulses;
private System.Windows.Forms.TextBox tbxDutPulsesMeasured;
private System.Windows.Forms.CheckBox cbxMeasuredDutPulses;
private System.Windows.Forms.Label lblMeasuredRefPulses;
}

View File

@ -1,40 +1,16 @@
/****************************************************************************************/
/*********************************************************************************************************************/
/*!@file FrmMainMiniPrf.cs
* @brief Main form for 'MiniPrf' - Single FM2014 Manual Flow Test Station:
* - Used to regulate one mechanical flow meter - 'DUT - Device under test',
* - Can be used to calibrate the 'REF - Reference meter'
*
*=======================================================================================\n
* @copyright
* @author Thomas Wiedebusch
* @date 2025-Nov-13
*
*_______________________________________________________________________________________\n
* Copyright (c) 2025..2026 SENSUS GmbH.\n
* All Rights Reserved.\n
* \n
* Confidential property of\n
* SENSUS GmbH,\n
* Meineckestr. 10, 30880 LAATZEN, GERMANY\n
* \n
*=======================================================================================\n
* @authors
* @details <i>Implements the serial communication to the FM2014 .</i>
*
*_______________________________________________________________________________________\n
* Thomas Wiedebusch\n
*
*
*=======================================================================================\n
* @version
*
*_______________________________________________________________________________________\n
* V1.00 13-Nov-2025..22-Dec-2025 by Thomas Wiedebusch\n
* - Initial.
*
*
*=======================================================================================\n
*/
//#define TEST_MULTIPLE_FM2014
* @copyright © SENSUS GmbH 2025..2026. All rights reserved.
**********************************************************************************************************************/
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Config;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core;
using Sensus.MiniPrf.Ui.Properties;
@ -48,9 +24,9 @@ using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts;
using Xylem.Common.CommonCore.Consts;
using Xylem.Common.Utils.ProcessExec.EventArguments;
using static Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts.FM2014CmdDef;
namespace Sensus.MiniPrf.Ui
{
@ -116,14 +92,6 @@ namespace Sensus.MiniPrf.Ui
private Int32 _addressIdx;
private Int32 _toleranceIdx;
// Backups of results from 'Manual REF Calibration' being able to restore those if a manual change
// of the REF pulses per cubic meter clears those fields. Bringing the last calibrated REF pulses
// per cubic meters back will automatically restore these results being able to adjust the measured
// volume in liters without a restart of the 'Manual REF Calibration'
private String _backupWeightScaleVolumeLitersStr;
private String _backupRefCalibrationResultPulsePerCmStr;
private String _backupMeasuredRefPulsesStr;
private Boolean _regulationSetupHasChanged;
#endregion Properties
@ -204,6 +172,12 @@ namespace Sensus.MiniPrf.Ui
break;
}
if (_fm2014Config != null)
{
// Restore baudrate
FM2014.Baudrate = _fm2014Config.Baudrate;
}
// FM2014 group box
lblConnectFM2014.Text = Resources.StrLblFM2014NotConnected;
lblConnectFM2014.ForeColor = ColorProcessFailed;
@ -219,9 +193,9 @@ namespace Sensus.MiniPrf.Ui
// Regulation Setup group box
gbxRegulationSetup.Text = Resources.StrGbxRegulationSetup;
lblRefPulsePerVolume.Text = Resources.StrLblRefPulsesPerCm;
tbxRefPulsePerCm.Text = "";
tbxRefPulsesPerCm.Text = "";
lblDutPulsePerVolume.Text = Resources.StrLblDutPulsesPerCm;
tbxDutPulsePerCm.Text = "";
tbxDutPulsesPerCm.Text = "";
lblScaleRefToDut.Text = Resources.StrLblScaleRefToDut;
tbxScaleRefToDut.Text = "";
lblAttenuation.Text = Resources.StrLblAttenuation;
@ -230,11 +204,11 @@ namespace Sensus.MiniPrf.Ui
// Manual REF Calibration group box
gbxManualRefCalibration.Text = Resources.StrGbxManualRefCalibration;
lblMeasuredRefPulses.Text = Resources.StrLblMeasuredRefPulses;
tbxMeasuredRefPulses.Text = "";
tbxRefPulsesMeasured.Text = "";
cbxMeasuredDutPulses.Text = Resources.StrLblMeasuredDutPulses;
tbxMeasuredDutPulses.Text = "";
tbxDutPulsesMeasured.Text = "";
lblWeightScaleVolume.Text = Resources.StrLblMeasuredWeightScaleVolume;
tbxManualInputVolumeLiters.Text = "";
tbxVolumeMeasuredLiters.Text = "";
lblPulseVolumeCmRelation.Text = Resources.StrLblRefPulsesPerCm;
tbxRefCalibrationResultPulsePerCm.Text = "";
btnManualRefCalibration.Text = Resources.StrBtnStartCalibration;
@ -314,7 +288,7 @@ namespace Sensus.MiniPrf.Ui
{
_cancellationTokenSource?.Cancel();
_frmHistory?.Close();
Fm2014?.Dispose();
FM2014.Dispose();
Dispose();
}
#endregion FormControls
@ -353,9 +327,9 @@ namespace Sensus.MiniPrf.Ui
btnFM2014Connect.Enabled = false;
// Disable manual input
tbxManualInputVolumeLiters.ReadOnly = true;
tbxRefPulsePerCm.ReadOnly = true;
tbxDutPulsePerCm.ReadOnly = true;
tbxVolumeMeasuredLiters.ReadOnly = true;
tbxRefPulsesPerCm.ReadOnly = true;
tbxDutPulsesPerCm.ReadOnly = true;
// Disable setting selections
cbxAttenuation.Enabled = false;
@ -381,9 +355,9 @@ namespace Sensus.MiniPrf.Ui
btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation;
// Enable manual input
tbxManualInputVolumeLiters.ReadOnly = false;
tbxRefPulsePerCm.ReadOnly = false;
tbxDutPulsePerCm.ReadOnly = false;
tbxVolumeMeasuredLiters.ReadOnly = false;
tbxRefPulsesPerCm.ReadOnly = false;
tbxDutPulsesPerCm.ReadOnly = false;
// Enable setting selections
cbxAttenuation.Enabled = true;
@ -441,7 +415,7 @@ namespace Sensus.MiniPrf.Ui
if (Fm2014 != null)
{
Fm2014.OnRawRecordReceived -= DataReceived_Handler;
Fm2014.Dispose();
FM2014.Dispose();
//dispose old meter
Fm2014 = null;
}
@ -522,7 +496,7 @@ namespace Sensus.MiniPrf.Ui
ActionControl(false);
MessageBox.Show(ex.Message, Resources.StrError, MessageBoxButtons.OK, MessageBoxIcon.Error);
LogErrorText(ex.Message);
Fm2014?.Dispose();
FM2014.Dispose();
}
}
@ -570,24 +544,26 @@ namespace Sensus.MiniPrf.Ui
/// <remarks date="2026-Jan-14..20" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void SetupHasChanged()
private void DutToRefRegulationSetupHasChanged()
{
_regulationSetupHasChanged = true;
btnSaveRegulationSetup.Enabled = true;
tbxRefFrequencyHz.Text = "";
Invoke(new Action(() =>
{
btnSaveRegulationSetup.Enabled = true;
btnDutToRefRegulation.Enabled = true;
tbxRefFrequencyHz.BackColor = ColorStandardDisplayField;
tbxActualFlowRateCmPerHour.Text = "";
tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField;
tbxActualMeasuredToleranceDutToRef.Text = "";
tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField;
tbxRefPulsePerCm.BackColor = ColorStandardInputField;
tbxDutPulsePerCm.BackColor = ColorStandardInputField;
tbxRefPulsesPerCm.BackColor = ColorStandardInputField;
tbxDutPulsesPerCm.BackColor = ColorStandardInputField;
tbxScaleRefToDut.BackColor = ColorStandardDisplayField;
tbxManualInputVolumeLiters.BackColor = ColorStandardInputField;
tbxVolumeMeasuredLiters.BackColor = ColorStandardInputField;
tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField;
}));
}
/// <summary>
@ -598,23 +574,27 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private Boolean UpdateRefToDutScale()
{
var retVal = true;
Invoke(new Action(() =>
{
tbxScaleRefToDut.Text = $@"{Fm2014.RefToDutScale_norm:F4}";
// Display error if scale doesn't fit
var tempRefToDutScale_norm = (Double)Fm2014.Ref_pulse_per_cm / Fm2014.Dut_pulse_per_cm;
if (tempRefToDutScale_norm < FM2014.RefToDutScaleMin ||
tempRefToDutScale_norm > FM2014.RefToDutScaleMax ||
Fm2014.RefToDutScale_norm < FM2014.RefToDutScaleMin ||
Fm2014.RefToDutScale_norm > FM2014.RefToDutScaleMax)
var tempRefToDutScale_norm = (Double)Fm2014.RefPulses_per_cm / Fm2014.DutPulses_per_cm;
if (tempRefToDutScale_norm < FM2014.REF_TO_DUT_SCALE_MIN ||
tempRefToDutScale_norm > FM2014.REF_TO_DUT_SCALE_MAX ||
Fm2014.RefToDutScale_norm < FM2014.REF_TO_DUT_SCALE_MIN ||
Fm2014.RefToDutScale_norm > FM2014.REF_TO_DUT_SCALE_MAX)
{
tbxScaleRefToDut.BackColor = ColorProcessFailed;
tbxScaleRefToDut.Text = Resources.StrError;
btnSaveRegulationSetup.Enabled = false;
return false;
btnDutToRefRegulation.Enabled = false;
retVal = false;
}
return true;
}));
return retVal;
}
/// <summary>
/// Common routine to reset the cancellation token on restart or new meter
@ -717,6 +697,143 @@ namespace Sensus.MiniPrf.Ui
}
#endregion HistoryWindow
#region Event handler
/// <summary>
/// Feedback from FM2014being parsed to GUI
/// </summary>
/// <remarks date="2023-Jan-04..21" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void DataReceived_Handler(Object sender, ProcessExecEventArgs e)
{
Invoke(new Action(() =>
{
// Process info
if (e.ActualProcessMessage != null)
lblActualProcess.Text = e.ActualProcessMessage;
lblActualProcess.Update();
SetTimeDisplay();
lblUpdateTimeValue.Update();
if (e.ActualProcessPercent != null && !_autoProgressBar && barSingleProgressUpdate.Visible)
barSingleProgressUpdate.Value = (Int32)e.ActualProcessPercent;
// Data dispatcher
var resp = (CmdResponse)e.SpecificInfoObj;
if (e.StatusReturn == StatusReturn.Failed)
{
LogErrorText(resp.AnswerStr);
//ErrorHandler(resp.CmdName);
}
else if (resp.IntValue == null && resp.DoubleValue == null)
{
LogText(resp.AnswerStr);
}
else if (resp.IntValue != null)
{
LogText($"{resp.AnswerStr}: {resp.IntValue:D} {resp.Unit}");
switch (resp.CmdName)
{
case CmdName.CMD_REF_GET_PLS_CTR:
case CmdName.CMD_REF_GET_PLS_CTR_BU:
tbxRefPulsesMeasured.Text = $@"{resp.IntValue:D}";
break;
case CmdName.CMD_DUT_GET_PLS_CTR:
case CmdName.CMD_DUT_GET_PLS_CTR_BU:
tbxDutPulsesMeasured.Text = $@"{resp.IntValue:D}";
break;
case CmdName.CMD_REF_LPP_SCALE:
tbxRefPulsesPerCm.Text = $@"{resp.IntValue:D}";
break;
case CmdName.CMD_DUT_LPP_SCALE:
tbxDutPulsesPerCm.Text = $@"{resp.IntValue:D}";
break;
case CmdName.CMD_MEAS_SET_ATTN:
var idx = cbxAttenuation.FindString($@"{resp.IntValue}");
cbxAttenuation.SelectedIndex = idx;
break;
case CmdName.CMD_GET_REF_FREQU:
tbxRefFrequencyHz.Text = $@"{resp.IntValue:D}";
tbxRefFrequencyDirectHz.Text = $@"{resp.IntValue:D}";
if (resp.IntValue < 1 || resp.IntValue > 254)
{
tbxRefFrequencyHz.BackColor = ColorProcessFailed;
tbxActualFlowRateCmPerHour.BackColor = ColorProcessFailed;
}
else
{
tbxRefFrequencyHz.BackColor = ColorStandardDisplayField;
tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField;
}
break;
case CmdName.CMD_RST_MEAS:
// Immediately lock all buttons and input fields until reset is finished
SetFM2014AccessLocked();
// Check countdown of reset method
if (resp.IntValue == 0)
ActionControl(false);
break;
}
}
else if (resp.DoubleValue != null)
{
LogText($"{resp.AnswerStr}: {resp.DoubleValue:F2} {resp.Unit}");
switch (resp.CmdName)
{
case CmdName.CMD_GET_UDTLC:
case CmdName.CMD_GET_DTLC:
tbxActualMeasuredToleranceDutToRef.Text = $@"{resp.DoubleValue:F2}";
if (resp.DoubleValue < -Fm2014.Tolerance_percent ||
resp.DoubleValue > Fm2014.Tolerance_percent)
{
tbxActualMeasuredToleranceDutToRef.BackColor = ColorProcessFailed;
}
else
{
tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField;
}
break;
case CmdName.CMD_REF_SET_SCALE:
tbxScaleRefToDut.Text = $@"{resp.DoubleValue:F4}";
break;
// DEBUG
case CmdName.CMD_GET_REF_PERIOD:
tbxRefPeriodMs.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_GET_DUT_PERIOD:
tbxDutPeriodMs.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_CAL_FREQU_REF_PERIOD:
tbxRefFrequencyFromRefPeriodHz.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_CAL_FREQU_DUT_PERIOD:
tbxDutFrequencyFromDutPeriodHz.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_CAL_FLOW_REF_FREQU:
tbxRefFlowRateFromRefFrequencyCmPerH.Text = $@"{resp.DoubleValue:F3}";
// TODO THW Check if the actual flow shall be taken based on 'REF Frequency'
tbxActualFlowRateCmPerHour.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_CAL_FLOW_REF_PERIOD:
tbxRefFlowRateFromRefPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}";
break;
case CmdName.CMD_CAL_FLOW_DUT_PERIOD:
tbxDutFlowRateFromDutPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}";
break;
}
}
// Catch the latest information
Update();
}));
}
#endregion Event Handler
#region Tools
/// <summary>
@ -754,12 +871,50 @@ namespace Sensus.MiniPrf.Ui
private void btnDutToRefRegulation_Click(Object sender, EventArgs e)
{
_startTime = DateTimeOffset.UtcNow;
if (FM2014.SharedCyclicMeasSequ == FM2014CmdDef.CyclicMeasSequ.IDLE)
Invoke(new Action(() =>
{
if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.IDLE)
{
if (FM2014.RegisteredFm2014s == null || FM2014.RegisteredFm2014s.Count == 0)
return;
// Take the settings from the inputs
UInt32 refPulses_per_cm = 1000;
UInt16 dutPulses_per_cm = 100;
UInt16 doublePulseDeadtime_ms = 0;
Byte currentOutputAttenuation = 1;
if (int.TryParse(tbxRefPulsesPerCm.Text, out var pulses_per_cm) &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MIN <= pulses_per_cm &&
FM2014.REF_PULSES_PER_CM_REGULATION_INPUT_MAX >= pulses_per_cm)
{
refPulses_per_cm = (UInt32)pulses_per_cm;
}
if (int.TryParse(tbxDutPulsesPerCm.Text, out pulses_per_cm) &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MIN <= pulses_per_cm &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MAX >= pulses_per_cm)
{
dutPulses_per_cm = (UInt16)pulses_per_cm;
}
//if (int.TryParse(tbxDoublePulseDeadtime.Text, out var deadtime_ms) &&
// FM2014.DOUBLE_PULSE_DEADTIME_MIN_ms <= deadtime_ms &&
// FM2014.DOUBLE_PULSE_DEADTIME_MAX_ms >= deadtime_ms)
//{
// doublePulseDeadtime_ms = (UInt16)deadtime_ms;
//}
if (byte.TryParse(cbxAttenuation.SelectedItem.ToString(), out var attenuation) &&
attenuation >= FM2014.CURRENT_OUTPUT_ATTENUATION_MIN &&
attenuation <= FM2014.CURRENT_OUTPUT_ATTENUATION_MAX)
{
currentOutputAttenuation = attenuation;
}
if (FM2014.RegulationMeasurement(refPulses_per_cm, dutPulses_per_cm, doublePulseDeadtime_ms,
currentOutputAttenuation))
{
ActionControl(true);
_autoProgressBar = true;
if (Fm2014.RegulationMeasurement())
{
ActionControl(true);
btnDutToRefRegulation.Text = Resources.StrBtnStopRegulation;
btnDutToRefRegulation.Enabled = true;
}
@ -769,12 +924,13 @@ namespace Sensus.MiniPrf.Ui
_autoProgressBar = false;
// Deactivate the button temporary to avoid repeated execution as the reset takes a certain time
btnDutToRefRegulation.Enabled = false;
Fm2014.ResetMeasurement();
FM2014.ResetHardwareAllDevices();
ActionControl(false);
btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation;
}
}));
}
/// <summary>
/// Start and stop the manual REF calibration measurement.
/// </summary>
@ -784,38 +940,34 @@ namespace Sensus.MiniPrf.Ui
private void btnManualRefCalibration_Click(Object sender, EventArgs e)
{
_startTime = DateTimeOffset.UtcNow;
if (FM2014.SharedCyclicMeasSequ == FM2014CmdDef.CyclicMeasSequ.IDLE)
Invoke(new Action(() =>
{
ActionControl(true);
tbxMeasuredRefPulses.Text = "";
tbxMeasuredDutPulses.Text = "";
tbxManualInputVolumeLiters.Text = "";
if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.IDLE)
{
tbxRefPulsesMeasured.Text = "";
tbxDutPulsesMeasured.Text = "";
tbxVolumeMeasuredLiters.Text = "";
tbxRefCalibrationResultPulsePerCm.Text = "";
tbxActualFlowRateCmPerHour.Text = "";
tbxActualMeasuredToleranceDutToRef.Text = "";
tbxRefFrequencyHz.Text = "";
_backupMeasuredRefPulsesStr = "";
_backupRefCalibrationResultPulsePerCmStr = "";
_backupWeightScaleVolumeLitersStr = "";
_autoProgressBar = true;
if (Fm2014.PulseCounterMeasurement(true, cbxMeasuredDutPulses.Checked))
if (FM2014.PulseCounterMeasurement(true, cbxMeasuredDutPulses.Checked))
{
_autoProgressBar = true;
ActionControl(true);
btnManualRefCalibration.Text = Resources.StrBtnStopCalibration;
btnManualRefCalibration.Enabled = true;
}
}
else
{
_autoProgressBar = false;
// Deactivate the button temporary to avoid repeated execution as the reset takes a certain time
btnManualRefCalibration.Enabled = false;
Fm2014.ResetMeasurement();
ActionControl(false);
btnManualRefCalibration.Text = Resources.StrBtnStartCalibration;
_autoProgressBar = false;
FM2014.ResetHardwareAllDevices();
}
}));
}
/// <summary>
@ -827,16 +979,20 @@ namespace Sensus.MiniPrf.Ui
private void cbxAttenuation_SelectedIndexChanged(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (Fm2014 != null)
{
if (byte.TryParse(cbxAttenuation.SelectedItem.ToString(), out var attenuation) &&
attenuation > 0 && attenuation <= 9 && Fm2014.Attenuation != attenuation)
attenuation >= FM2014.CURRENT_OUTPUT_ATTENUATION_MIN &&
attenuation <= FM2014.CURRENT_OUTPUT_ATTENUATION_MAX &&
Fm2014.CurrentOutputAttenuation != attenuation)
{
Fm2014.Attenuation = attenuation;
_regulationSetupHasChanged = true;
btnSaveRegulationSetup.Enabled = true;
}
}
}));
}
/// <summary>
@ -848,6 +1004,8 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private void cbxFM2014BaseSettings_SelectedValueChanged(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (_toleranceIdx != cbxFM2014TolerancePercent.SelectedIndex ||
_addressIdx != cbxFM2014Address.SelectedIndex ||
@ -858,6 +1016,7 @@ namespace Sensus.MiniPrf.Ui
_comPortIdx = cbxFM2014ComPort.SelectedIndex;
StoreFM2014Settings();
}
}));
}
/// <summary>
@ -870,7 +1029,7 @@ namespace Sensus.MiniPrf.Ui
/// </remarks>
private void btnSaveRegulationSetup_Click(Object sender, EventArgs e)
{
if (Fm2014 != null && Fm2014.SaveStandAloneMeasurement())
if (Fm2014 != null && FM2014.StoreAllConfigurations())
{
_regulationSetupHasChanged = false;
btnSaveRegulationSetup.Enabled = false;
@ -887,9 +1046,12 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private void chkUseDampedTolerance_CheckedChanged(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (Fm2014 != null)
Fm2014.UseDampedTolerance = chkUseDampedTolerance.Checked;
}));
}
/// <summary>
@ -924,7 +1086,7 @@ namespace Sensus.MiniPrf.Ui
if (e.KeyCode == Keys.Enter)
{
tbxRefPulsesPerCm_Leave(this, null);
SelectNextControl(ActiveControl, true, true, true, true);
SelectNextControl(tbxDutPulsesPerCm, true, true, true, true);
}
else if (!MaskEditIntegerInput(e.KeyCode))
{
@ -955,60 +1117,48 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private void tbxRefPulsesPerCm_Leave(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (Fm2014 == null)
return;
if (string.IsNullOrEmpty(tbxRefPulsePerCm.Text))
if (string.IsNullOrEmpty(tbxRefPulsesPerCm.Text))
{
tbxRefPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}";
tbxRefPulsesPerCm.BackColor = ColorProcessFailed;
btnSaveRegulationSetup.Enabled = false;
btnDutToRefRegulation.Enabled = false;
return;
}
// Setup FM2014
if (int.TryParse(tbxRefPulsePerCm.Text, out var pulses_per_cm))
{
//Backup the actual setting to detect changes
var backupPulses_per_cm = Fm2014.Ref_pulse_per_cm;
var backupPulses_per_cm = Fm2014.RefPulses_per_cm;
Fm2014.Ref_pulse_per_cm = (UInt32)pulses_per_cm;
// Output the Fm2014 setting to avoid wrong display of invalid ranges as this will be
// limited during the setup of the FM2014 property!
tbxRefPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}";
// Parse and check limits
if (int.TryParse(tbxRefPulsesPerCm.Text, out var pulses_per_cm) &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MIN <= pulses_per_cm &&
FM2014.REF_PULSES_PER_CM_REGULATION_INPUT_MAX >= pulses_per_cm)
{
// During setup of the 'Ref_pulse_per_cm' the 'RefToDutScaleStr' will be generated
Fm2014.RefPulses_per_cm = (UInt32)pulses_per_cm;
if (!UpdateRefToDutScale())
{
tbxRefPulsePerCm.BackColor = ColorProcessFailed;
tbxRefPulsesPerCm.BackColor = ColorProcessFailed;
return;
}
// Check if values have changed and need to be updated in the standalone setup
if (backupPulses_per_cm != Fm2014.Ref_pulse_per_cm)
if (backupPulses_per_cm != pulses_per_cm || tbxRefPulsesPerCm.BackColor == ColorProcessFailed)
{
SetupHasChanged();
DutToRefRegulationSetupHasChanged();
}
// SPECIAL BACKUP AND RESTORE FOR REF CALIBRATION
// If the REF pulses per cubic meter have been changed manually, the 'Manual REF Calibration'
// fields have to be cleared if those are different. A backup to restore it may be useful.
if (!tbxRefPulsePerCm.Text.Equals(tbxRefCalibrationResultPulsePerCm.Text) &&
!string.IsNullOrEmpty(tbxRefCalibrationResultPulsePerCm.Text))
}
else
{
_backupMeasuredRefPulsesStr = tbxMeasuredRefPulses.Text;
tbxMeasuredRefPulses.Text = "";
_backupRefCalibrationResultPulsePerCmStr = tbxRefCalibrationResultPulsePerCm.Text;
tbxRefCalibrationResultPulsePerCm.Text = "";
_backupWeightScaleVolumeLitersStr = tbxManualInputVolumeLiters.Text;
tbxManualInputVolumeLiters.Text = "";
}
// Restore values if REF pulses per cubic meters is back to the calibrated one
else if (tbxRefPulsePerCm.Text.Equals(_backupRefCalibrationResultPulsePerCmStr))
{
tbxMeasuredRefPulses.Text = _backupMeasuredRefPulsesStr;
tbxRefCalibrationResultPulsePerCm.Text = _backupRefCalibrationResultPulsePerCmStr;
tbxManualInputVolumeLiters.Text = _backupWeightScaleVolumeLitersStr;
}
tbxRefPulsesPerCm.BackColor = ColorProcessFailed;
}
}));
}
/// <summary>
@ -1056,37 +1206,48 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private void tbxDutPulsesPerCm_Leave(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (Fm2014 == null)
return;
if (string.IsNullOrEmpty(tbxDutPulsePerCm.Text))
if (string.IsNullOrEmpty(tbxDutPulsesPerCm.Text))
{
tbxDutPulsePerCm.Text = $@"{Fm2014.Dut_pulse_per_cm:D}";
tbxDutPulsesPerCm.BackColor = ColorProcessFailed;
btnSaveRegulationSetup.Enabled = false;
btnDutToRefRegulation.Enabled = false;
return;
}
// Setup FM2014
if (int.TryParse(tbxDutPulsePerCm.Text, out var pulses_per_cm))
{
//Backup the actual setting to detect changes
var backupPulses_per_cm = Fm2014.Dut_pulse_per_cm;
// Try to set the new calculated REF pulses limited by the property setter
Fm2014.Dut_pulse_per_cm = (UInt32)pulses_per_cm;
// Output the Fm2014 setting to avoid wrong display of invalid ranges as this will be
// limited during the setup of the FM2014 property!
tbxDutPulsePerCm.Text = $@"{Fm2014.Dut_pulse_per_cm:D}";
var backupPulses_per_cm = Fm2014.DutPulses_per_cm;
// Parse and check limits
if (int.TryParse(tbxDutPulsesPerCm.Text, out var pulses_per_cm) &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MIN <= pulses_per_cm &&
FM2014.PULSES_PER_CM_REGULATION_SETUP_MAX >= pulses_per_cm)
{
// During setup of the 'Dut_pulse_per_cm' the 'RefToDutScaleStr' will be generated
Fm2014.DutPulses_per_cm = (UInt16)pulses_per_cm;
if (!UpdateRefToDutScale())
{
tbxDutPulsePerCm.BackColor = ColorProcessFailed;
tbxDutPulsesPerCm.BackColor = ColorProcessFailed;
return;
}
// Check if values have changed and need to be updated in the standalone setup
if (backupPulses_per_cm != Fm2014.Dut_pulse_per_cm)
if (backupPulses_per_cm != Fm2014.DutPulses_per_cm)
{
SetupHasChanged();
DutToRefRegulationSetupHasChanged();
}
}
else
{
tbxDutPulsesPerCm.BackColor = ColorProcessFailed;
}
}));
}
/// <summary>
@ -1136,54 +1297,63 @@ namespace Sensus.MiniPrf.Ui
/// - Initial.
/// </remarks>
private void tbxManualInputVolumeLiters_Leave(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
if (Fm2014 == null)
return;
if (string.IsNullOrEmpty(tbxRefPulsePerCm.Text))
if (!string.IsNullOrEmpty(tbxRefPulsesMeasured.Text) &&
string.IsNullOrEmpty(tbxVolumeMeasuredLiters.Text))
{
tbxManualInputVolumeLiters.Text = @"0";
tbxVolumeMeasuredLiters.BackColor = ColorProcessFailed;
return;
}
// Calculate REF pulses per cubic meter
if (int.TryParse(tbxMeasuredRefPulses.Text, out var pulses) && pulses > 0 &&
int.TryParse(tbxManualInputVolumeLiters.Text, out var liters) && liters > 0)
{
//Backup the actual setting to detect changes
var backupPulses_per_cm = Fm2014.Ref_pulse_per_cm;
var backupPulses_per_cm = Fm2014.RefPulses_per_cm;
// Calculate REF pulses per cubic meter
if (int.TryParse(tbxRefPulsesMeasured.Text, out var pulses) && pulses > 0 &&
int.TryParse(tbxVolumeMeasuredLiters.Text, out var liters) && liters > 0)
{
// Calculate the new pulse ratio based on the manual calibration
var pulses_per_cm = (UInt32)(pulses / (liters / 1000.0) + 0.5);
// Try to set the new calculated REF pulses limited by the property setter
Fm2014.Ref_pulse_per_cm = pulses_per_cm;
Fm2014.RefPulses_per_cm = pulses_per_cm;
// If this succeeded, then update the new manual calibrated value
if (pulses_per_cm == Fm2014.Ref_pulse_per_cm)
if (pulses_per_cm == Fm2014.RefPulses_per_cm)
{
tbxRefCalibrationResultPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}";
tbxRefPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}";
tbxManualInputVolumeLiters.BackColor = ColorStandardInputField;
tbxRefCalibrationResultPulsePerCm.Text = $@"{Fm2014.RefPulses_per_cm:D}";
tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField;
tbxRefPulsesPerCm.Text = $@"{Fm2014.RefPulses_per_cm:D}";
tbxVolumeMeasuredLiters.BackColor = ColorStandardInputField;
tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField;
if (!UpdateRefToDutScale())
{
tbxManualInputVolumeLiters.BackColor = ColorProcessFailed;
tbxVolumeMeasuredLiters.BackColor = ColorProcessFailed;
tbxRefCalibrationResultPulsePerCm.BackColor = ColorProcessFailed;
return;
}
// Check if values have changed and need to be updated in the standalone setup
if (backupPulses_per_cm != Fm2014.Ref_pulse_per_cm)
if (backupPulses_per_cm != Fm2014.RefPulses_per_cm)
{
SetupHasChanged();
DutToRefRegulationSetupHasChanged();
}
}
else
{
tbxManualInputVolumeLiters.BackColor = ColorProcessFailed;
tbxVolumeMeasuredLiters.BackColor = ColorProcessFailed;
tbxRefCalibrationResultPulsePerCm.BackColor = ColorProcessFailed;
tbxRefCalibrationResultPulsePerCm.Text = Resources.StrError;
}
}
}));
}
/// <summary>
@ -1192,6 +1362,8 @@ namespace Sensus.MiniPrf.Ui
/// <param name="sender"></param>
/// <param name="e"></param>
private void picFM2014_Click(Object sender, EventArgs e)
{
Invoke(new Action(() =>
{
grpBoxDebug.Visible = !grpBoxDebug.Visible;
if (Fm2014 != null)
@ -1200,6 +1372,7 @@ namespace Sensus.MiniPrf.Ui
//gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible;
gbxRegulationSetup.Visible = !grpBoxDebug.Visible;
}));
}
/// <summary>
@ -1217,134 +1390,5 @@ namespace Sensus.MiniPrf.Ui
#endregion Buttons and Controls
#region Event handler
/// <summary>
/// Feedback from FM2014being parsed to GUI
/// </summary>
/// <remarks date="2023-Jan-04..21" author="Thomas Wiedebusch">
/// - Initial.
/// </remarks>
private void DataReceived_Handler(Object sender, ProcessExecEventArgs e)
{
Invoke(new Action(() =>
{
// Process info
if (e.ActualProcessMessage != null)
lblActualProcess.Text = e.ActualProcessMessage;
lblActualProcess.Update();
SetTimeDisplay();
lblUpdateTimeValue.Update();
if (e.ActualProcessPercent != null && !_autoProgressBar && barSingleProgressUpdate.Visible)
barSingleProgressUpdate.Value = (Int32)e.ActualProcessPercent;
// Data dispatcher
var resp = (FM2014CmdDef.CmdResponse)e.SpecificInfoObj;
if (e.StatusReturn == StatusReturn.Failed)
{
LogErrorText(resp.AnswerStr);
//ErrorHandler(resp.CmdName);
}
else if (resp.IntValue == null && resp.DoubleValue == null)
{
LogText(resp.AnswerStr);
}
else if (resp.IntValue != null)
{
LogText($"{resp.AnswerStr}: {resp.IntValue:D} {resp.SiUnit}");
switch (resp.CmdName)
{
case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR:
case FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR_BU:
tbxMeasuredRefPulses.Text = $@"{resp.IntValue:D}";
break;
case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR:
case FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR_BU:
tbxMeasuredDutPulses.Text = $@"{resp.IntValue:D}";
break;
case FM2014CmdDef.CmdName.CMD_REF_LPP_SCALE:
tbxRefPulsePerCm.Text = $@"{resp.IntValue:D}";
break;
case FM2014CmdDef.CmdName.CMD_DUT_LPP_SCALE:
tbxDutPulsePerCm.Text = $@"{resp.IntValue:D}";
break;
case FM2014CmdDef.CmdName.CMD_MEAS_SET_ATTN:
var idx = cbxAttenuation.FindString($@"{resp.IntValue}");
cbxAttenuation.SelectedIndex = idx;
break;
case FM2014CmdDef.CmdName.CMD_GET_REF_FREQU:
tbxRefFrequencyHz.Text = $@"{resp.IntValue:D}";
tbxRefFrequencyDirectHz.Text = $@"{resp.IntValue:D}";
if (resp.IntValue < 1 || resp.IntValue > 254)
{
tbxRefFrequencyHz.BackColor = ColorProcessFailed;
tbxActualFlowRateCmPerHour.BackColor = ColorProcessFailed;
}
else
{
tbxRefFrequencyHz.BackColor = ColorStandardDisplayField;
tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField;
}
break;
}
}
else if (resp.DoubleValue != null)
{
LogText($"{resp.AnswerStr}: {resp.DoubleValue:F2} {resp.SiUnit}");
switch (resp.CmdName)
{
case FM2014CmdDef.CmdName.CMD_GET_UDTLC:
case FM2014CmdDef.CmdName.CMD_GET_DTLC:
tbxActualMeasuredToleranceDutToRef.Text = $@"{resp.DoubleValue:F2}";
if (resp.DoubleValue < -Fm2014.Tolerance_percent ||
resp.DoubleValue > Fm2014.Tolerance_percent)
{
tbxActualMeasuredToleranceDutToRef.BackColor = ColorProcessFailed;
}
else
{
tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField;
}
break;
case FM2014CmdDef.CmdName.CMD_REF_SET_SCALE:
tbxScaleRefToDut.Text = $@"{resp.DoubleValue:F4}";
break;
// DEBUG
case FM2014CmdDef.CmdName.CMD_GET_REF_PERIOD:
tbxRefPeriodMs.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_GET_DUT_PERIOD:
tbxDutPeriodMs.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_CAL_FREQU_REF_PERIOD:
tbxRefFrequencyFromRefPeriodHz.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_CAL_FREQU_DUT_PERIOD:
tbxDutFrequencyFromDutPeriodHz.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_FREQU:
tbxRefFlowRateFromRefFrequencyCmPerH.Text = $@"{resp.DoubleValue:F3}";
// TODO THW Check if the actual flow shall be taken based on 'REF Frequency'
tbxActualFlowRateCmPerHour.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_CAL_FLOW_REF_PERIOD:
tbxRefFlowRateFromRefPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}";
break;
case FM2014CmdDef.CmdName.CMD_CAL_FLOW_DUT_PERIOD:
tbxDutFlowRateFromDutPeriodCmPerH.Text = $@"{resp.DoubleValue:F3}";
break;
}
}
// Catch the latest information
Update();
}));
}
#endregion
}
}