From 91fa956e413b23ef08fc3594f79ab8275da294c6 Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Wed, 11 Feb 2026 17:16:23 +0100 Subject: [PATCH] MiniPrf: - adapted to static methods in FM2014 --- .../FM2014/FM2014Core/FM2014.cs | 16 +- .../Fm2014sTest/FM2014TestBenchWindow.xaml.cs | 62 +- MiniPrf/Ui/FrmMainMiniPrf.Designer.cs | 106 +-- MiniPrf/Ui/FrmMainMiniPrf.cs | 808 +++++++++--------- 4 files changed, 531 insertions(+), 461 deletions(-) diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs index faa445a7..0e9be667 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs @@ -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)) { diff --git a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs index b8192531..5c38ef4a 100644 --- a/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs +++ b/FM2014TestApp/Ui/Fm2014sTest/FM2014TestBenchWindow.xaml.cs @@ -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,7 +1141,8 @@ namespace Sensus.Ui.FM2014TestBench break; case CmdName.CMD_DUT_GET_PLS_CTR: case CmdName.CMD_DUT_GET_PLS_CTR_BU: - UpdateTextBox(tbxDutPulsesMeasured, $"{resp.IntValue:D}"); + if (firstFm2014 != null && firstFm2014.Address == fm2014.Address) + UpdateTextBox(tbxDutPulsesMeasured, $"{resp.IntValue:D}"); ucFm2014.SetValue(CTR_LBL_IDX_DUT_PLS, $"{resp.IntValue:D}"); break; case CmdName.CMD_REF_LPP_SCALE: @@ -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; diff --git a/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs b/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs index 252d65eb..896617ef 100644 --- a/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs +++ b/MiniPrf/Ui/FrmMainMiniPrf.Designer.cs @@ -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; } diff --git a/MiniPrf/Ui/FrmMainMiniPrf.cs b/MiniPrf/Ui/FrmMainMiniPrf.cs index 0e645b54..1461b9f1 100644 --- a/MiniPrf/Ui/FrmMainMiniPrf.cs +++ b/MiniPrf/Ui/FrmMainMiniPrf.cs @@ -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 Implements the serial communication to the FM2014 . * -*_______________________________________________________________________________________\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,11 +496,11 @@ namespace Sensus.MiniPrf.Ui ActionControl(false); MessageBox.Show(ex.Message, Resources.StrError, MessageBoxButtons.OK, MessageBoxIcon.Error); LogErrorText(ex.Message); - Fm2014?.Dispose(); + FM2014.Dispose(); } } -#endregion BoardControls + #endregion BoardControls #region ProcessControls @@ -570,24 +544,26 @@ namespace Sensus.MiniPrf.Ui /// /// - Initial. /// - private void SetupHasChanged() + private void DutToRefRegulationSetupHasChanged() { _regulationSetupHasChanged = true; - btnSaveRegulationSetup.Enabled = true; - tbxRefFrequencyHz.Text = ""; - tbxRefFrequencyHz.BackColor = ColorStandardDisplayField; - tbxActualFlowRateCmPerHour.Text = ""; - tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField; - tbxActualMeasuredToleranceDutToRef.Text = ""; - tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField; + Invoke(new Action(() => + { + btnSaveRegulationSetup.Enabled = true; + btnDutToRefRegulation.Enabled = true; - tbxRefPulsePerCm.BackColor = ColorStandardInputField; - tbxDutPulsePerCm.BackColor = ColorStandardInputField; - tbxScaleRefToDut.BackColor = ColorStandardDisplayField; + tbxRefFrequencyHz.BackColor = ColorStandardDisplayField; + tbxActualFlowRateCmPerHour.BackColor = ColorStandardDisplayField; + tbxActualMeasuredToleranceDutToRef.BackColor = ColorStandardDisplayField; - tbxManualInputVolumeLiters.BackColor = ColorStandardInputField; - tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField; + tbxRefPulsesPerCm.BackColor = ColorStandardInputField; + tbxDutPulsesPerCm.BackColor = ColorStandardInputField; + tbxScaleRefToDut.BackColor = ColorStandardDisplayField; + + tbxVolumeMeasuredLiters.BackColor = ColorStandardInputField; + tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField; + })); } /// @@ -599,22 +575,26 @@ namespace Sensus.MiniPrf.Ui /// private Boolean UpdateRefToDutScale() { - 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 retVal = true; + Invoke(new Action(() => { - tbxScaleRefToDut.BackColor = ColorProcessFailed; - tbxScaleRefToDut.Text = Resources.StrError; - btnSaveRegulationSetup.Enabled = false; - return false; - } + tbxScaleRefToDut.Text = $@"{Fm2014.RefToDutScale_norm:F4}"; - return true; + // Display error if scale doesn't fit + 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; + btnDutToRefRegulation.Enabled = false; + retVal = false; + } + })); + return retVal; } /// /// 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 + + /// + /// Feedback from FM2014being parsed to GUI + /// + /// + /// - Initial. + /// + 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 /// @@ -754,27 +871,66 @@ namespace Sensus.MiniPrf.Ui private void btnDutToRefRegulation_Click(Object sender, EventArgs e) { _startTime = DateTimeOffset.UtcNow; - if (FM2014.SharedCyclicMeasSequ == FM2014CmdDef.CyclicMeasSequ.IDLE) + Invoke(new Action(() => { - ActionControl(true); - _autoProgressBar = true; - if (Fm2014.RegulationMeasurement()) + if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.IDLE) { - btnDutToRefRegulation.Text = Resources.StrBtnStopRegulation; - btnDutToRefRegulation.Enabled = true; - } - } - else - { - _autoProgressBar = false; - // Deactivate the button temporary to avoid repeated execution as the reset takes a certain time - btnDutToRefRegulation.Enabled = false; - Fm2014.ResetMeasurement(); - ActionControl(false); - btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation; - } + 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)) + { + _autoProgressBar = true; + ActionControl(true); + btnDutToRefRegulation.Text = Resources.StrBtnStopRegulation; + btnDutToRefRegulation.Enabled = true; + } + } + else + { + _autoProgressBar = false; + // Deactivate the button temporary to avoid repeated execution as the reset takes a certain time + btnDutToRefRegulation.Enabled = false; + FM2014.ResetHardwareAllDevices(); + ActionControl(false); + btnDutToRefRegulation.Text = Resources.StrBtnStartRegulation; + } + })); } + /// /// Start and stop the manual REF calibration measurement. /// @@ -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 = ""; - tbxRefCalibrationResultPulsePerCm.Text = ""; - tbxActualFlowRateCmPerHour.Text = ""; - tbxActualMeasuredToleranceDutToRef.Text = ""; - tbxRefFrequencyHz.Text = ""; - - _backupMeasuredRefPulsesStr = ""; - _backupRefCalibrationResultPulsePerCmStr = ""; - _backupWeightScaleVolumeLitersStr = ""; - - _autoProgressBar = true; - - if (Fm2014.PulseCounterMeasurement(true, cbxMeasuredDutPulses.Checked)) + if (FM2014.SharedCyclicMeasSequ == CyclicMeasSequ.IDLE) { - btnManualRefCalibration.Text = Resources.StrBtnStopCalibration; - btnManualRefCalibration.Enabled = true; + tbxRefPulsesMeasured.Text = ""; + tbxDutPulsesMeasured.Text = ""; + tbxVolumeMeasuredLiters.Text = ""; + tbxRefCalibrationResultPulsePerCm.Text = ""; + tbxActualFlowRateCmPerHour.Text = ""; + tbxActualMeasuredToleranceDutToRef.Text = ""; + tbxRefFrequencyHz.Text = ""; + + 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; - } + else + { + // Deactivate the button temporary to avoid repeated execution as the reset takes a certain time + btnManualRefCalibration.Enabled = false; + _autoProgressBar = false; + FM2014.ResetHardwareAllDevices(); + } + })); } /// @@ -827,16 +979,20 @@ namespace Sensus.MiniPrf.Ui private void cbxAttenuation_SelectedIndexChanged(Object sender, EventArgs e) { - if (Fm2014 != null) + Invoke(new Action(() => { - if (byte.TryParse(cbxAttenuation.SelectedItem.ToString(), out var attenuation) && - attenuation > 0 && attenuation <= 9 && Fm2014.Attenuation != attenuation) + if (Fm2014 != null) { - Fm2014.Attenuation = attenuation; - _regulationSetupHasChanged = true; - btnSaveRegulationSetup.Enabled = true; + if (byte.TryParse(cbxAttenuation.SelectedItem.ToString(), out var attenuation) && + attenuation >= FM2014.CURRENT_OUTPUT_ATTENUATION_MIN && + attenuation <= FM2014.CURRENT_OUTPUT_ATTENUATION_MAX && + Fm2014.CurrentOutputAttenuation != attenuation) + { + _regulationSetupHasChanged = true; + btnSaveRegulationSetup.Enabled = true; + } } - } + })); } /// @@ -849,15 +1005,18 @@ namespace Sensus.MiniPrf.Ui /// private void cbxFM2014BaseSettings_SelectedValueChanged(Object sender, EventArgs e) { - if (_toleranceIdx != cbxFM2014TolerancePercent.SelectedIndex || - _addressIdx != cbxFM2014Address.SelectedIndex || - _comPortIdx != cbxFM2014ComPort.SelectedIndex) + Invoke(new Action(() => { - _toleranceIdx = cbxFM2014TolerancePercent.SelectedIndex; - _addressIdx = cbxFM2014Address.SelectedIndex; - _comPortIdx = cbxFM2014ComPort.SelectedIndex; - StoreFM2014Settings(); - } + if (_toleranceIdx != cbxFM2014TolerancePercent.SelectedIndex || + _addressIdx != cbxFM2014Address.SelectedIndex || + _comPortIdx != cbxFM2014ComPort.SelectedIndex) + { + _toleranceIdx = cbxFM2014TolerancePercent.SelectedIndex; + _addressIdx = cbxFM2014Address.SelectedIndex; + _comPortIdx = cbxFM2014ComPort.SelectedIndex; + StoreFM2014Settings(); + } + })); } /// @@ -870,7 +1029,7 @@ namespace Sensus.MiniPrf.Ui /// private void btnSaveRegulationSetup_Click(Object sender, EventArgs e) { - if (Fm2014 != null && Fm2014.SaveStandAloneMeasurement()) + if (Fm2014 != null && FM2014.StoreAllConfigurations()) { _regulationSetupHasChanged = false; btnSaveRegulationSetup.Enabled = false; @@ -888,8 +1047,11 @@ namespace Sensus.MiniPrf.Ui /// private void chkUseDampedTolerance_CheckedChanged(Object sender, EventArgs e) { - if (Fm2014 != null) - Fm2014.UseDampedTolerance = chkUseDampedTolerance.Checked; + Invoke(new Action(() => + { + if (Fm2014 != null) + Fm2014.UseDampedTolerance = chkUseDampedTolerance.Checked; + })); } /// @@ -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)) { @@ -956,59 +1118,47 @@ namespace Sensus.MiniPrf.Ui /// private void tbxRefPulsesPerCm_Leave(Object sender, EventArgs e) { - if (Fm2014 == null) - return; - - if (string.IsNullOrEmpty(tbxRefPulsePerCm.Text)) + Invoke(new Action(() => { - tbxRefPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}"; - } + if (Fm2014 == null) + 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; - - 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}"; - // During setup of the 'Ref_pulse_per_cm' the 'RefToDutScaleStr' will be generated - if (!UpdateRefToDutScale()) + if (string.IsNullOrEmpty(tbxRefPulsesPerCm.Text)) { - tbxRefPulsePerCm.BackColor = ColorProcessFailed; + tbxRefPulsesPerCm.BackColor = ColorProcessFailed; + btnSaveRegulationSetup.Enabled = false; + btnDutToRefRegulation.Enabled = false; return; } - // Check if values have changed and need to be updated in the standalone setup - if (backupPulses_per_cm != Fm2014.Ref_pulse_per_cm) - { - SetupHasChanged(); - } + //Backup the actual setting to detect changes + var backupPulses_per_cm = Fm2014.RefPulses_per_cm; - // SPECIAL BACKUP AND RESTORE FOR REF CALIBRATION + // 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 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)) - { - _backupMeasuredRefPulsesStr = tbxMeasuredRefPulses.Text; - tbxMeasuredRefPulses.Text = ""; - _backupRefCalibrationResultPulsePerCmStr = tbxRefCalibrationResultPulsePerCm.Text; - tbxRefCalibrationResultPulsePerCm.Text = ""; - _backupWeightScaleVolumeLitersStr = tbxManualInputVolumeLiters.Text; - tbxManualInputVolumeLiters.Text = ""; + if (!UpdateRefToDutScale()) + { + tbxRefPulsesPerCm.BackColor = ColorProcessFailed; + return; + } + + // Check if values have changed and need to be updated in the standalone setup + if (backupPulses_per_cm != pulses_per_cm || tbxRefPulsesPerCm.BackColor == ColorProcessFailed) + { + DutToRefRegulationSetupHasChanged(); + } } - // Restore values if REF pulses per cubic meters is back to the calibrated one - else if (tbxRefPulsePerCm.Text.Equals(_backupRefCalibrationResultPulsePerCmStr)) + else { - tbxMeasuredRefPulses.Text = _backupMeasuredRefPulsesStr; - tbxRefCalibrationResultPulsePerCm.Text = _backupRefCalibrationResultPulsePerCmStr; - tbxManualInputVolumeLiters.Text = _backupWeightScaleVolumeLitersStr; + tbxRefPulsesPerCm.BackColor = ColorProcessFailed; } - } + })); } /// @@ -1057,36 +1207,47 @@ namespace Sensus.MiniPrf.Ui /// private void tbxDutPulsesPerCm_Leave(Object sender, EventArgs e) { - if (Fm2014 == null) - return; + Invoke(new Action(() => + { + if (Fm2014 == null) + return; - if (string.IsNullOrEmpty(tbxDutPulsePerCm.Text)) - { - tbxDutPulsePerCm.Text = $@"{Fm2014.Dut_pulse_per_cm:D}"; - } - // 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}"; - // During setup of the 'Dut_pulse_per_cm' the 'RefToDutScaleStr' will be generated - if (!UpdateRefToDutScale()) + if (string.IsNullOrEmpty(tbxDutPulsesPerCm.Text)) { - tbxDutPulsePerCm.BackColor = ColorProcessFailed; + tbxDutPulsesPerCm.BackColor = ColorProcessFailed; + btnSaveRegulationSetup.Enabled = false; + btnDutToRefRegulation.Enabled = false; return; } - // Check if values have changed and need to be updated in the standalone setup - if (backupPulses_per_cm != Fm2014.Dut_pulse_per_cm) + //Backup the actual setting to detect changes + 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) { - SetupHasChanged(); + // During setup of the 'Dut_pulse_per_cm' the 'RefToDutScaleStr' will be generated + Fm2014.DutPulses_per_cm = (UInt16)pulses_per_cm; + + if (!UpdateRefToDutScale()) + { + tbxDutPulsesPerCm.BackColor = ColorProcessFailed; + return; + } + + // Check if values have changed and need to be updated in the standalone setup + if (backupPulses_per_cm != Fm2014.DutPulses_per_cm) + { + DutToRefRegulationSetupHasChanged(); + } } - } + else + { + tbxDutPulsesPerCm.BackColor = ColorProcessFailed; + } + })); } /// @@ -1137,53 +1298,62 @@ namespace Sensus.MiniPrf.Ui /// private void tbxManualInputVolumeLiters_Leave(Object sender, EventArgs e) { - if (Fm2014 == null) - return; + Invoke(new Action(() => + { + if (Fm2014 == null) + return; + + if (!string.IsNullOrEmpty(tbxRefPulsesMeasured.Text) && + string.IsNullOrEmpty(tbxVolumeMeasuredLiters.Text)) + { + tbxVolumeMeasuredLiters.BackColor = ColorProcessFailed; + return; + } - if (string.IsNullOrEmpty(tbxRefPulsePerCm.Text)) - { - tbxManualInputVolumeLiters.Text = @"0"; - } - // 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 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; - - // If this succeeded, then update the new manual calibrated value - if (pulses_per_cm == Fm2014.Ref_pulse_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) { - tbxRefCalibrationResultPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}"; - tbxRefPulsePerCm.Text = $@"{Fm2014.Ref_pulse_per_cm:D}"; - tbxManualInputVolumeLiters.BackColor = ColorStandardInputField; - tbxRefCalibrationResultPulsePerCm.BackColor = ColorStandardDisplayField; - if (!UpdateRefToDutScale()) + // 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.RefPulses_per_cm = pulses_per_cm; + + // If this succeeded, then update the new manual calibrated value + if (pulses_per_cm == Fm2014.RefPulses_per_cm) { - tbxManualInputVolumeLiters.BackColor = ColorProcessFailed; - return; + 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()) + { + 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.RefPulses_per_cm) + { + DutToRefRegulationSetupHasChanged(); + } } - - // Check if values have changed and need to be updated in the standalone setup - if (backupPulses_per_cm != Fm2014.Ref_pulse_per_cm) + else { - SetupHasChanged(); + tbxVolumeMeasuredLiters.BackColor = ColorProcessFailed; + tbxRefCalibrationResultPulsePerCm.BackColor = ColorProcessFailed; + tbxRefCalibrationResultPulsePerCm.Text = Resources.StrError; } } - else - { - tbxManualInputVolumeLiters.BackColor = ColorProcessFailed; - tbxRefCalibrationResultPulsePerCm.BackColor = ColorProcessFailed; - tbxRefCalibrationResultPulsePerCm.Text = Resources.StrError; - } - } + })); } /// @@ -1193,13 +1363,16 @@ namespace Sensus.MiniPrf.Ui /// private void picFM2014_Click(Object sender, EventArgs e) { - grpBoxDebug.Visible = !grpBoxDebug.Visible; - if (Fm2014 != null) - Fm2014.RequestDebugInformation = grpBoxDebug.Visible; + Invoke(new Action(() => + { + grpBoxDebug.Visible = !grpBoxDebug.Visible; + if (Fm2014 != null) + Fm2014.RequestDebugInformation = grpBoxDebug.Visible; - //gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible; - gbxRegulationSetup.Visible = !grpBoxDebug.Visible; + //gbxDutToRefRegulation.Visible = !grpBoxDebug.Visible; + gbxRegulationSetup.Visible = !grpBoxDebug.Visible; + })); } /// @@ -1217,134 +1390,5 @@ namespace Sensus.MiniPrf.Ui #endregion Buttons and Controls - #region Event handler - - /// - /// Feedback from FM2014being parsed to GUI - /// - /// - /// - Initial. - /// - 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 } }