From 92bcd46549014aeb3870e039b058d8ef99660d59 Mon Sep 17 00:00:00 2001 From: Milan Hanajik Date: Mon, 15 Feb 2016 15:16:44 +0100 Subject: [PATCH] Working on 2Hz correction --- .../iPerlCommunicationForm.cs | 56 +++++++++++++++++++ .../WaterMeters/iPerl/WaterMeter.cs | 52 ++++++++++++++++- 2 files changed, 107 insertions(+), 1 deletion(-) diff --git a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs index 8099b2cc5..dd827340c 100644 --- a/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs +++ b/TestBenchFramework/BenchControl/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs @@ -1106,6 +1106,62 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication } + /// + /// Write the calculated 2Hz correction factor to the memory. + /// + /// Water meter object + /// String passed to caller + /// true on success + static CommErr Write2HzCorrection(WaterMeters.iPerl.WaterMeter wm, ref string resultStr) + { + if (wm.CommFailed) return CommErr.CommFailed; + + /// Write Q2 corrections + double hz2CorrectionFactor = wm.Hz2CorrectionFactor(); + if (hz2CorrectionFactor == 0) + { + resultStr = string.Format("2Hz factors = 0 (writing bypassed)"); + return CommErr.None; + } + + if (OpenPort(wm) != 0) return CommErr.OpenPort; /// Open RFID port + + CommErr error = CommErr.Write; + + Byte hz2CorrectionByte = (byte)((int)Math.Round(hz2CorrectionFactor) & 0x000000FF); + byte[] wrData = new byte[1] { hz2CorrectionByte }; + /// + for (int j = 0; j < cfg.MaxCommRetries; j++) + { + if (0 == WriteRequestPort(wm, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, 1, wrData, cfg.CommTimeout)) { error = CommErr.None; break; } + } + + if (error == CommErr.None) + { + error = CommErr.Verify; + + /// Read calibration + byte[] rdData = null; + for (int j = 0; j < cfg.MaxCommRetries; j++) + { + if ((0 == ReadRequestPort(wm, MessageID.MetrologyMemory, Hz2CorrFactorsAddr, 1, out rdData, cfg.CommTimeout)) && + (rdData != null) && (rdData.Length == 2) && (rdData[0] == hz2CorrectionByte)) + { + error = CommErr.None; + resultStr = string.Format("2Hz factor = {0}", (SByte)hz2CorrectionByte); + rfidDataLogger.Warn(wm.Name + ": " + resultStr); + wm.Current2HzCorrection = hz2CorrectionFactor; + break; + } + } + } + + ClosePort(wm); /// Close RFID port + + return error; + } + + /// /// Called when communication with one watermeter is completed /// diff --git a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs index ebafcdcc5..51d0b39ee 100644 --- a/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs +++ b/TestBenchFramework/BenchControl/WaterMeters/iPerl/WaterMeter.cs @@ -113,8 +113,9 @@ namespace TBF.BenchControl.WaterMeters.iPerl public double Q2ErrorWOCorrection; public bool Q2CorrectionDone; - public double CurrentQ2Correction; + public double CurrentQ2Correction; + public double Current2HzCorrection; /// Result of the last test used to calculate Q2 correction factors, etc public Results.Entities.MeterTestRslt LastTestResult; @@ -219,6 +220,55 @@ namespace TBF.BenchControl.WaterMeters.iPerl return corrFactor; } + + /// + /// 2 Hz correction factor calculated from two Q3 tests - done at 2Hz and at 8Hz. + /// This factors should be used only for DN32 and DN40 meters. + /// + /// 2 Hz correction factor + public double Hz2CorrectionFactor() + { + Q2ErrorWOCorrection = LastTestResult.Error; + + if (Math.Abs(LastTestResult.Error) <= 0.5) + { + Q2CorrectionDone = false; + return 0; /// No Q2 correction if error < +/-0.5 % + } + + double A = 16.0 / ScalingFactor(); /// Raw units per ml: DN15=16, DN20=8, DN25=4, DN32=2, DN40=1 + const double B = 8.0; /// Raw units per minute, 8 + const double C = B * 60.0; /// Raw units per hour, 480 + double D = C / A; /// ml correction per hour + double F = D / (NominalTestFlow * 10.0); /// Error corrected with 8 Raw Units per minute [%] + double G = F / B; /// Error corrected with 1 Raw Unit per minute [%] + + double errLimitLo = LastTestResult.ErrLimLo() + LastTestResult.Uncertainty(); + double errLimitHi = LastTestResult.ErrLimHi() - LastTestResult.Uncertainty(); + + if (LastTestResult.Error < errLimitLo) return 0; /// No Q2 correction if error too large -> WM failed + if (LastTestResult.Error > errLimitHi) return 0; /// No Q2 correction if error too large -> WM failed + + double volumeMeterErrLimLo = LastTestResult.VolumeRef * (100.0 + errLimitLo) / 100.0; + double volumeMeterErrLimHi = LastTestResult.VolumeRef * (100.0 + errLimitHi) / 100.0; + + double corrFactorHi = (-1) * (errLimitLo / G) * (LastTestResult.VolumeRef / volumeMeterErrLimLo); /// > 0 + double corrFactorLo = (-1) * (errLimitHi / G) * (LastTestResult.VolumeRef / volumeMeterErrLimHi); /// < 0 + + double corrFactor = (-1) * (LastTestResult.Error / G) * (LastTestResult.VolumeRef / LastTestResult.VolumeMeter); + double origCalulatedCorrFactor = corrFactor; + + log.WarnFormat("Q2 correction: {0}, corrFactor={4}, error={3}% [Lo={1}%, Hi={2}%]", + Name, + errLimitLo.ToString("F1"), + errLimitHi.ToString("F1"), + LastTestResult.Error.ToString("F2"), + corrFactor.ToString("F1")); + + Q2CorrectionDone = true; + return corrFactor; + } + /// Name set by the test, to be used as a part of the opto-data log file name public string TestName;