From 963df837dc2648adc43efacb63d974479aacc0ac Mon Sep 17 00:00:00 2001 From: Thomas Wiedebusch Date: Mon, 12 Jan 2026 16:16:43 +0100 Subject: [PATCH] FM2014: - pulse measurements --- .../FM2014/FM2014Core/Consts/FM2014CmdDef.cs | 230 +++++++++--------- .../FM2014/FM2014Core/FM2014.cs | 110 ++++++--- .../Properties/Resources.Designer.cs | 9 + .../FM2014Core/Properties/Resources.de.resx | 3 + .../FM2014Core/Properties/Resources.resx | 3 + MiniPrf/Ui/FrmMainMiniPrf.cs | 12 +- 6 files changed, 213 insertions(+), 154 deletions(-) diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/FM2014CmdDef.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/FM2014CmdDef.cs index 7d5ef897..3e890a9a 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/FM2014CmdDef.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Consts/FM2014CmdDef.cs @@ -46,7 +46,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// Command definition /// - public enum CmdDef + public enum CmdName { /// /// @@ -212,7 +212,11 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// /// - CMD_ADDR_PC + CMD_ADDR_PC, + /// + /// + /// + CMD_NA } /// @@ -224,12 +228,12 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// Individual addressed command with answer /// INDIVIDUAL_WA, - + /// /// Individual addressed command without answer /// INDIVIDUAL_NA, - + /// /// Broadcast command without answer to address 0 or individual without answer /// @@ -239,12 +243,12 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// Assembly of command information and functional code /// - public struct CmdTblEntry + public struct Cmd { /// /// Enumerator of command name acronym /// - public readonly CmdDef CmdName; + public readonly CmdName CmdName; /// /// Code being sent to FM2014 as character @@ -268,7 +272,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// Code being sent to FM2014 as character /// Command type regarding the address (broadcast or individual) and answer /// Multilingual command information string - public CmdTblEntry(CmdDef cmdName, Char cmdCodeChar, CmdType cmdType, String cmdInfoStr) + public Cmd(CmdName cmdName, Char cmdCodeChar, CmdType cmdType, String cmdInfoStr) { CmdName = cmdName; CmdCodeChar = cmdCodeChar; @@ -277,6 +281,88 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co } } + /// + /// Resolution of FM2014 timer for measurement of pulse width + /// + public const Double FM2014_TMR_RESOLUTION_s = 334e-6; + + /// + /// FM2014 Ascii string delimiter + /// + public const Char END_OF_STRING = '\r'; + + /// + /// Character for address assignment in advance to the address number + /// + public const Char ADDR_RECORD_CHAR = '*'; + + /// + /// Address assignment validation behind the address number + /// + public const Char ADDR_VALIDATION_CHAR = '@'; + + // Unicode chars for command table + private const Char UNICODE_ACK = '\u0006'; + private const Char UNICODE_DLE = '\u0010'; + private const Char UNICODE_DC1 = '\u0011'; + private const Char UNICODE_DC2 = '\u0012'; + + /// + /// Complete command table + /// + public static List CmdTbl = new List + { + // FM2014 control and information + new Cmd(CmdName.CMD_UNLOCK_ERASE, '&', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgUnlockErase), + new Cmd(CmdName.CMD_DEF_MEAS_SETUP, '%', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDefMeasSetup), + new Cmd(CmdName.CMD_BOOT_MODE, '$', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgBootMode), + new Cmd(CmdName.CMD_PRINT_INFO, '?', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgPrintInfo), + new Cmd(CmdName.CMD_BAUDRATE_ALL, '=', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgBaudrateAll), + new Cmd(CmdName.CMD_GET_VIRTUAL_ADDRESS, ' ', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetVirtualAddress), + new Cmd(CmdName.CMD_SERIAL, '#', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgSerial), + new Cmd(CmdName.CMD_GET_STATUS, UNICODE_ACK, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetStatus), + new Cmd(CmdName.CMD_SET_VIRTUAL_ADDRESS, 'N', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgSetVirtualAddress), + new Cmd(CmdName.CMD_PRINT_STATISTICS, '!', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgPrintStatistics), + //measurement reset + new Cmd(CmdName.CMD_RST_MEAS, 'R', CmdType.BROADCAST, Resources.StrCmdMsgRstMeas), + // Double impulse detection settings + new Cmd(CmdName.CMD_SET_DPLS_LOCK_TMR, 'S', CmdType.BROADCAST, Resources.StrCmdMsgDplsLockTmr), + new Cmd(CmdName.CMD_SET_DPLS_LOCK_MULT, 's', CmdType.BROADCAST, Resources.StrCmdMsgDplsLockMult), + new Cmd(CmdName.CMD_SET_DBPL_UNLOCK, 'G', CmdType.BROADCAST, Resources.StrCmdMsgSetDbplUnlock), + // Main measurement pulse settings and readout + new Cmd(CmdName.CMD_DUT_SET_PLS, 'H', CmdType.BROADCAST, Resources.StrCmdMsgDutSetPls), + new Cmd(CmdName.CMD_REF_SET_PLS, 'M', CmdType.BROADCAST, Resources.StrCmdMsgRefSetPls), + new Cmd(CmdName.CMD_DUT_GET_PLS_RMN, 'I', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsRmn), + new Cmd(CmdName.CMD_REF_GET_PLS_RMN, 'J', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsRmn), + // Pulse counters start, readout and backup + new Cmd(CmdName.CMD_REF_STR_PLS_CTR, 'O', CmdType.BROADCAST, Resources.StrCmdMsgRefStrPlsCtr), + new Cmd(CmdName.CMD_DUT_STR_PLS_CTR, 'Q', CmdType.BROADCAST, Resources.StrCmdMsgDutStrPlsCtr), + new Cmd(CmdName.CMD_REF_GET_PLS_CTR, 'L', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsCtr), + new Cmd(CmdName.CMD_DUT_GET_PLS_CTR, 'U', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsCtr), + new Cmd(CmdName.CMD_REF_GET_PLS_CTR_BU, 'l', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsCtrBu), + new Cmd(CmdName.CMD_DUT_GET_PLS_CTR_BU, 'u', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsCtrBu), + new Cmd(CmdName.CMD_REF_DUT_STR_PLS_CTR, 'o', CmdType.BROADCAST, Resources.StrCmdMsgRefDutStrPlsCtr), + new Cmd(CmdName.CMD_REF_DUT_BU_PLS_CTR, 'q', CmdType.BROADCAST, Resources.StrCmdMsgRefDutBuPlsCtr), + // General measurement setup + new Cmd(CmdName.CMD_REF_SET_SCALE, 'K', CmdType.BROADCAST, Resources.StrCmdMsgRefSetScale), + new Cmd(CmdName.CMD_DUT_LPP_SCALE, 'V', CmdType.INDIVIDUAL_NA, Resources.StrCmdMsgDutLppScale), + new Cmd(CmdName.CMD_REF_LPP_SCALE, 'W', CmdType.INDIVIDUAL_NA, Resources.StrCmdMsgRefLppScale), + new Cmd(CmdName.CMD_MEAS_SET_ATTN, 'T', CmdType.BROADCAST, Resources.StrCmdMsgMeasSetAttn), + // Measurement result request + new Cmd(CmdName.CMD_DUT_GET_TMR, 'X', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetTmr), + new Cmd(CmdName.CMD_REF_GET_TMR, 'Y', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetTmr), + new Cmd(CmdName.CMD_GET_UDTLC, 'Z', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetUdtlc), + new Cmd(CmdName.CMD_GET_DTLC, 'z', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetDtlc), + new Cmd(CmdName.CMD_GET_REF_PERIOD, UNICODE_DLE, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetRefPeriod), + new Cmd(CmdName.CMD_GET_DUT_PERIOD, UNICODE_DC1, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetDutPeriod), + new Cmd(CmdName.CMD_GET_REF_FREQU, UNICODE_DC2, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetRefFrequ), + // Adjustment, place here Ids which may represent digital numbers from A to F + new Cmd(CmdName.CMD_COR_CURRENT, 'C', CmdType.BROADCAST, Resources.StrCmdMsgCorCurrent), + new Cmd(CmdName.CMD_SET_XTR_MAX, '+', CmdType.BROADCAST, Resources.StrCmdMsgSetXtrMax), + new Cmd(CmdName.CMD_SET_XTR_MIN, '-', CmdType.BROADCAST, Resources.StrCmdMsgSetXtrMin), + new Cmd(CmdName.CMD_ADDR_PC, 'A', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgAddrPc) + }; + /// /// Combine constant string returns from FM2014 firmware to multilingual information /// @@ -286,7 +372,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// Hard coded return string from FM2014 /// public String FM2014ErrorReturnStr; - + /// /// Multilingual forwarded string to GUI /// @@ -307,7 +393,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// Table of error codes received from FM2014 /// - public static readonly CmdErrorMsg[] CmdErrorCodes = + public static readonly CmdErrorMsg[] CmdErrorCodes = { new CmdErrorMsg ("Parameter is out of range!", Resources.StrCmdRespErrorParamOutOfRange), new CmdErrorMsg ("Command not supported!", Resources.StrCmdRespErrorCmdNotSupported), @@ -325,32 +411,32 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// FM2014 command identifier /// - public CmdDef CmdId { get; private set; } - + public CmdName CmdId { get; private set; } + /// /// Optional raw answer from FM2014 /// public String AnswerStr { get; private set; } - + /// /// Optional integer value /// public Int32? IntValue { get; private set; } - + /// /// Optional double value /// public Double? DoubleValue { get; private set; } - + /// /// Measurement SI unit /// public String SiUnit { get; private set; } - + /// /// Ctor /// - public CmdResponse(CmdDef cmdId, String answerStr, Int32? intValue = null, Double? doubleValue = null, + public CmdResponse(CmdName cmdId, String answerStr, Int32? intValue = null, Double? doubleValue = null, String siUnit = "") { CmdId = cmdId; @@ -361,100 +447,6 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co } } - /// - /// Resolution of FM2014 timer for measurement of pulse width - /// - public const Double FM2014_TMR_RESOLUTION_s = 334e-6; - - /// - /// FM2014 Ascii string delimiter - /// - public const Char END_OF_STRING = '\r'; - - /// - /// Character for address assignment in advance to the address number - /// - public const Char ADDR_RECORD_CHAR = '*'; - - /// - /// Address assignment validation behind the address number - /// - public const Char ADDR_VALIDATION_CHAR = '@'; - - /// - /// Complete command table - /// - public static List CmdTbl; - - // Unicode chars for command table - private const Char UNICODE_ACK = '\u0006'; - private const Char UNICODE_DLE = '\u0010'; - private const Char UNICODE_DC1 = '\u0011'; - private const Char UNICODE_DC2 = '\u0012'; - - /// - /// Ctor - /// - /// command code to send to the FM2014 - /// - /// - Initial. - /// - static FM2014CmdDef() - { - CmdTbl = new List - { - // FM2014 control and information - new CmdTblEntry(CmdDef.CMD_UNLOCK_ERASE, '&', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgUnlockErase), - new CmdTblEntry(CmdDef.CMD_DEF_MEAS_SETUP, '%', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDefMeasSetup), - new CmdTblEntry(CmdDef.CMD_BOOT_MODE, '$', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgBootMode), - new CmdTblEntry(CmdDef.CMD_PRINT_INFO, '?', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgPrintInfo), - new CmdTblEntry(CmdDef.CMD_BAUDRATE_ALL, '=', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgBaudrateAll), - new CmdTblEntry(CmdDef.CMD_GET_VIRTUAL_ADDRESS, ' ', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetVirtualAddress), - new CmdTblEntry(CmdDef.CMD_SERIAL, '#', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgSerial), - new CmdTblEntry(CmdDef.CMD_GET_STATUS, UNICODE_ACK, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetStatus), - new CmdTblEntry(CmdDef.CMD_SET_VIRTUAL_ADDRESS, 'N', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgSetVirtualAddress), - new CmdTblEntry(CmdDef.CMD_PRINT_STATISTICS, '!', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgPrintStatistics), - //measurement reset - new CmdTblEntry(CmdDef.CMD_RST_MEAS, 'R', CmdType.BROADCAST, Resources.StrCmdMsgRstMeas), - // Double impulse detection settings - new CmdTblEntry(CmdDef.CMD_SET_DPLS_LOCK_TMR, 'S', CmdType.BROADCAST, Resources.StrCmdMsgDplsLockTmr), - new CmdTblEntry(CmdDef.CMD_SET_DPLS_LOCK_MULT, 's', CmdType.BROADCAST, Resources.StrCmdMsgDplsLockMult), - new CmdTblEntry(CmdDef.CMD_SET_DBPL_UNLOCK, 'G', CmdType.BROADCAST, Resources.StrCmdMsgSetDbplUnlock), - // Main measurement pulse settings and readout - new CmdTblEntry(CmdDef.CMD_DUT_SET_PLS, 'H', CmdType.BROADCAST, Resources.StrCmdMsgDutSetPls), - new CmdTblEntry(CmdDef.CMD_REF_SET_PLS, 'M', CmdType.BROADCAST, Resources.StrCmdMsgRefSetPls), - new CmdTblEntry(CmdDef.CMD_DUT_GET_PLS_RMN, 'I', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsRmn), - new CmdTblEntry(CmdDef.CMD_REF_GET_PLS_RMN, 'J', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsRmn), - // Pulse counters start, readout and backup - new CmdTblEntry(CmdDef.CMD_REF_STR_PLS_CTR, 'O', CmdType.BROADCAST, Resources.StrCmdMsgRefStrPlsCtr), - new CmdTblEntry(CmdDef.CMD_DUT_STR_PLS_CTR, 'Q', CmdType.BROADCAST, Resources.StrCmdMsgDutStrPlsCtr), - new CmdTblEntry(CmdDef.CMD_REF_GET_PLS_CTR, 'L', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsCtr), - new CmdTblEntry(CmdDef.CMD_DUT_GET_PLS_CTR, 'U', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsCtr), - new CmdTblEntry(CmdDef.CMD_REF_GET_PLS_CTR_BU, 'l', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetPlsCtrBu), - new CmdTblEntry(CmdDef.CMD_DUT_GET_PLS_CTR_BU, 'u', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetPlsCtrBu), - new CmdTblEntry(CmdDef.CMD_REF_DUT_STR_PLS_CTR, 'o', CmdType.BROADCAST, Resources.StrCmdMsgRefDutStrPlsCtr), - new CmdTblEntry(CmdDef.CMD_REF_DUT_BU_PLS_CTR, 'q', CmdType.BROADCAST, Resources.StrCmdMsgRefDutBuPlsCtr), - // General measurement setup - new CmdTblEntry(CmdDef.CMD_REF_SET_SCALE, 'K', CmdType.BROADCAST, Resources.StrCmdMsgRefSetScale), - new CmdTblEntry(CmdDef.CMD_DUT_LPP_SCALE, 'V', CmdType.INDIVIDUAL_NA, Resources.StrCmdMsgDutLppScale), - new CmdTblEntry(CmdDef.CMD_REF_LPP_SCALE, 'W', CmdType.INDIVIDUAL_NA, Resources.StrCmdMsgRefLppScale), - new CmdTblEntry(CmdDef.CMD_MEAS_SET_ATTN, 'T', CmdType.BROADCAST, Resources.StrCmdMsgMeasSetAttn), - // Measurement result request - new CmdTblEntry(CmdDef.CMD_DUT_GET_TMR, 'X', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgDutGetTmr), - new CmdTblEntry(CmdDef.CMD_REF_GET_TMR, 'Y', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgRefGetTmr), - new CmdTblEntry(CmdDef.CMD_GET_UDTLC, 'Z', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetUdtlc), - new CmdTblEntry(CmdDef.CMD_GET_DTLC, 'z', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetDtlc), - new CmdTblEntry(CmdDef.CMD_GET_REF_PERIOD, UNICODE_DLE, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetRefPeriod), - new CmdTblEntry(CmdDef.CMD_GET_DUT_PERIOD, UNICODE_DC1, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetDutPeriod), - new CmdTblEntry(CmdDef.CMD_GET_REF_FREQU, UNICODE_DC2, CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgGetRefFrequ), - // Adjustment, place here Ids which may represent digital numbers from A to F - new CmdTblEntry(CmdDef.CMD_COR_CURRENT, 'C', CmdType.BROADCAST, Resources.StrCmdMsgCorCurrent), - new CmdTblEntry(CmdDef.CMD_SET_XTR_MAX, '+', CmdType.BROADCAST, Resources.StrCmdMsgSetXtrMax), - new CmdTblEntry(CmdDef.CMD_SET_XTR_MIN, '-', CmdType.BROADCAST, Resources.StrCmdMsgSetXtrMin), - new CmdTblEntry(CmdDef.CMD_ADDR_PC, 'A', CmdType.INDIVIDUAL_WA, Resources.StrCmdMsgAddrPc) - }; - } - /// /// Get char command code from command name /// @@ -463,11 +455,11 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// - Initial. /// - public static Char GetCmdChar(CmdDef cmdName) + public static Char GetCmdChar(CmdName cmdName) { return (from ct in CmdTbl - where ct.CmdName == cmdName - select ct.CmdCodeChar).FirstOrDefault(); + where ct.CmdName == cmdName + select ct.CmdCodeChar).FirstOrDefault(); } /// @@ -478,11 +470,11 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// - Initial. /// - public static String GetCmdInfo(CmdDef cmdName) + public static String GetCmdInfo(CmdName cmdName) { return (from ct in CmdTbl - where ct.CmdName == cmdName - select ct.CmdInfoStr).FirstOrDefault(); + where ct.CmdName == cmdName + select ct.CmdInfoStr).FirstOrDefault(); } /// @@ -493,11 +485,11 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Co /// /// - Initial. /// - public static CmdType GetCmdCmdType(CmdDef cmdName) + public static CmdType GetCmdCmdType(CmdName cmdName) { return (from ct in CmdTbl - where ct.CmdName == cmdName - select ct.CmdType).FirstOrDefault(); + where ct.CmdName == cmdName + select ct.CmdType).FirstOrDefault(); } } } diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs index 1e262705..5e25e077 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/FM2014.cs @@ -35,8 +35,10 @@ using System; using System.Globalization; using System.IO.Ports; +using System.Threading; using System.Threading.Tasks; using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Consts; +using Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Properties; using Xylem.Common.CommonCore.Consts; using Xylem.Common.Utils.ProcessExec.EventArguments; @@ -207,63 +209,89 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core } /// - /// Reference calibration with volume or weight-scale: - /// - Count pulses on REF, - /// - Manual input of volume. + /// Pulse counter measurement: + /// - REF counter, + /// - DUT counter, + /// - REF and DUT counters together. /// + /// request to count REF pulses + /// request to count DUT pulses /// - /// + /// /// - Initial. /// - public Boolean ManualRefCalibration() + public Boolean StartPulseCounting(Boolean refCtrOn = true, Boolean dutCtrOn = false) { - if (SerialPort == null || !SerialPort.IsOpen) + if (SerialPort == null || !SerialPort.IsOpen || (!refCtrOn && !dutCtrOn)) { return false; } - // Stop receive task - if (ReceiveTaskIsActive) - { - ReceiveTaskIsActive = false; - return true; - } - ReceiveTaskIsActive = true; + var cmdName = FM2014CmdDef.CmdName.CMD_NA; // Prepare REF-pulse counter measurement try { - SerialPort.Write($"{FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdDef.CMD_REF_STR_PLS_CTR)}{_eos}"); + if (refCtrOn && dutCtrOn) + cmdName = FM2014CmdDef.CmdName.CMD_REF_DUT_STR_PLS_CTR; + else if (refCtrOn) + cmdName = FM2014CmdDef.CmdName.CMD_REF_STR_PLS_CTR; + else + cmdName = FM2014CmdDef.CmdName.CMD_DUT_STR_PLS_CTR; + + var cmdCodeChar = FM2014CmdDef.GetCmdChar(cmdName); + SerialPort.Write($"{cmdCodeChar}{_eos}"); } catch (Exception e) { - Console.WriteLine(e); + var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message); + OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response, + statusReturn: StatusReturn.Failed)); } // Measurement Loop Task.Run(() => { // Get the process information - var info = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdDef.CMD_REF_GET_PLS_CTR); - var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdDef.CMD_REF_GET_PLS_CTR); + var infoRef = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR); + var cmdCodeRef = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR); + var infoDut = FM2014CmdDef.GetCmdInfo(FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR); + var cmdCodeDut = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR); do { try { - SerialPort.Write($"{cmdCode}{_eos}"); - var refPulseStr = SerialPort.ReadTo($"{_eos}"); - - if (int.TryParse(refPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var refPulses)) + if (refCtrOn) { - var response = new FM2014CmdDef.CmdResponse(FM2014CmdDef.CmdDef.CMD_REF_GET_PLS_CTR, "", - refPulses); - OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(info, specificInfoObj: response)); + SerialPort.Write($"{cmdCodeRef}{_eos}"); + var refPulseStr = SerialPort.ReadTo($"{_eos}"); + + if (int.TryParse(refPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var refPulses)) + { + var response = new FM2014CmdDef.CmdResponse(FM2014CmdDef.CmdName.CMD_REF_GET_PLS_CTR, "", + refPulses); + OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoRef, specificInfoObj: response)); + } + } + if (dutCtrOn) + { + SerialPort.Write($"{cmdCodeDut}{_eos}"); + var dutPulseStr = SerialPort.ReadTo($"{_eos}"); + + if (int.TryParse(dutPulseStr, NumberStyles.HexNumber, new CultureInfo("en"), out var dutPulses)) + { + var response = new FM2014CmdDef.CmdResponse(FM2014CmdDef.CmdName.CMD_DUT_GET_PLS_CTR, "", + dutPulses); + OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(infoDut, specificInfoObj: response)); + } } } catch (Exception e) { - Console.WriteLine(e); + var response = new FM2014CmdDef.CmdResponse(cmdName, e.Message); + OnRawRecordReceived?.Invoke(this, new ProcessExecEventArgs(Resources.StrError, specificInfoObj: response, + statusReturn: StatusReturn.Failed)); } //Thread.Sleep(500); @@ -305,7 +333,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core var fields = FullId.Split('.'); FwVersion = fields[1]; - var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdDef.CMD_SERIAL); + var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_SERIAL); // Read out the serial number of this FM2014 SerialPort.Write($"{cmdCode}{_eos}"); SerialNumber = SerialPort.ReadTo($"{_eos}"); @@ -325,9 +353,36 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core return IsLoggedOn; } + /// + /// Reset the measurement but only if receive task is active. + /// + /// + /// + /// - Initial. + /// + public Boolean ResetMeasurement() + { + if (SerialPort == null || !SerialPort.IsOpen) + return false; + + if (!ReceiveTaskIsActive) + return true; + + ReceiveTaskIsActive = false; + // Reset measurement + var cmdCode = FM2014CmdDef.GetCmdChar(FM2014CmdDef.CmdName.CMD_RST_MEAS); + // Read out the serial number of this FM2014 + SerialPort?.Write($"{cmdCode}{_eos}"); + // Wait until FM2014 calibration finished + Thread.Sleep(4000); + + return true; + } + /// public Boolean Logout() { + ResetMeasurement(); IsLoggedOn = false; SerialPort?.Close(); return SerialPort != null && !SerialPort.IsOpen; @@ -336,8 +391,7 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core /// public void Dispose() { - IsLoggedOn = false; - SerialPort?.Close(); + Logout(); SerialPort?.Dispose(); } #endregion methods diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs index abb6264d..ff533ea2 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.Designer.cs @@ -483,5 +483,14 @@ namespace Sensus.Common.Hardware.WaterMeter.MechanicalMeter.FM2014.FM2014Core.Pr return ResourceManager.GetString("StrCmdRespErrorRefTimeout", resourceCulture); } } + + /// + /// Looks up a localized string similar to ERROR. + /// + internal static string StrError { + get { + return ResourceManager.GetString("StrError", resourceCulture); + } + } } } diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx index 0fe35e8a..52befa89 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.de.resx @@ -259,4 +259,7 @@ + + FEHLER + \ No newline at end of file diff --git a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx index 3c2b6c6a..b0c9f1e5 100644 --- a/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx +++ b/Common/Hardware/WaterMeter/MechanicalMeter/FM2014/FM2014Core/Properties/Resources.resx @@ -258,4 +258,7 @@ + + ERROR + \ No newline at end of file diff --git a/MiniPrf/Ui/FrmMainMiniPrf.cs b/MiniPrf/Ui/FrmMainMiniPrf.cs index 652ea1e5..5e552b3f 100644 --- a/MiniPrf/Ui/FrmMainMiniPrf.cs +++ b/MiniPrf/Ui/FrmMainMiniPrf.cs @@ -254,7 +254,6 @@ namespace Sensus.MiniPrf.Ui private void FrmMainMiniPrf_FormClosed(Object sender, FormClosedEventArgs e) { _frmHistory?.Close(); - _fm2014?.Logout(); _fm2014?.Dispose(); Dispose(); } @@ -618,18 +617,17 @@ namespace Sensus.MiniPrf.Ui _startTime = DateTimeOffset.UtcNow; ActionControl(true); btnDutToRefRegulation.Enabled = false; - if (_fm2014.ManualRefCalibration()) + if (_fm2014.StartPulseCounting()) { btnManualRefCalibration.Text = Resources.StrBtnStopCalibration; } } else { - if (_fm2014.ManualRefCalibration()) - { - ActionControl(false); - btnManualRefCalibration.Text = Resources.StrBtnStartCalibration; - } + btnManualRefCalibration.Enabled = false; + _fm2014.ResetMeasurement(); + ActionControl(false); + btnManualRefCalibration.Text = Resources.StrBtnStartCalibration; } }