diff --git a/TestBenchFramework/BenchControl/Events.cs b/TestBenchFramework/BenchControl/Events.cs index ac942b0df..25b30ba00 100644 --- a/TestBenchFramework/BenchControl/Events.cs +++ b/TestBenchFramework/BenchControl/Events.cs @@ -12,6 +12,9 @@ namespace TBF.BenchControl Overload, Failed, Busy, + Busy1, /// + Busy2, /// Used by Mettler-Toledo Multi to distinguish which scale was queried + Busy3, /// } /// diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Multi/BalanceDev.cs b/TestBenchFramework/BenchControl/MettlerToledo/Multi/BalanceDev.cs index 765dc8ada..eca11353a 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Multi/BalanceDev.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Multi/BalanceDev.cs @@ -30,6 +30,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi public override string ToString() { return string.Format("MettlerToledo.Multi.Balance({0})", Cfg.ToString(1)); } protected readonly BalanceCfg balanceCfg; + protected static BalanceCfg balance1Cfg; /// /// Enumeration of balances via static fields and methods @@ -45,17 +46,18 @@ namespace TBF.BenchControl.MettlerToledo.Multi /// protected int balanceNr; /// 0-based balance number - protected SerialPort serialPort; - protected StringBuilder stringBuilder; + protected static SerialPort serialPort; + protected static StringBuilder stringBuilder; - public int BalanceNr { get { return balanceNr; } } - public float Capacity { get { return balanceCfg.Capacity; } } + public int BalanceNr { get { return balanceNr; } } + public int IdNr { get { return balanceCfg.IdNr; } } + public float Capacity { get { return balanceCfg.Capacity; } } public float Resolution { get { return balanceCfg.Resolution; } } public int EmptyTimeSec { get { return balanceCfg.EmptyTimeSec; } } /// The state of the mass measurement public MsrmntState MsrmntState { get { return msrmntState; } } - protected MsrmntState msrmntState; + protected static MsrmntState msrmntState; /// The mass after StartMassMeasurement() when MsrmntState == MsrmntState.Valid public float Mass { get { return Masses[balanceNr]; } } @@ -78,6 +80,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi : base(cfg) { balanceCfg = cfg; + if (cfg.IdNr == 1) balance1Cfg = cfg; balanceNr = nextBalanceIdx++; Masses = new float[nextBalanceIdx]; /// (re)initialize the static array of masses of all balances @@ -95,7 +98,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi public void Initialize() { - msrmntState = MsrmntState.Busy; /// Data not valid yet + msrmntState = MsrmntState.Failed; /// Data not valid yet if (balanceCfg.DebugLevel == DebugMode.Simulate) return; @@ -121,6 +124,54 @@ namespace TBF.BenchControl.MettlerToledo.Multi return (mass <= balanceCfg.Empty); } + /// + /// Get a stable mass measurement + /// + public static bool GetStableMassMeasurement(int scaleId, string name) + { + if (balance1Cfg.DebugLevel == DebugMode.Simulate) return true; + + if (msrmntState == MsrmntState.Busy || + msrmntState == MsrmntState.Busy1 || + msrmntState == MsrmntState.Busy2 || + msrmntState == MsrmntState.Busy3) + { + log.WarnFormat("{0} - GetStableMassMeasurement() returns false ... measurementState == {1}", name, msrmntState.ToString()); + return false; + } + + msrmntState = (MsrmntState)((int)MsrmntState.Busy + scaleId); + stringBuilder.Clear(); + string serialData = string.Format("AR WT0{0}01\r\n", scaleId); + serialPort.Write(serialData); + log.InfoFormat("{0} - GetStableMassMeasurement() ... \"{1}\" sent", name, serialData); + return true; + } + + /// + /// Get an immediate mass measurement + /// + public static bool GetImmediateMassMeasurement(int scaleId, string name) + { + if (balance1Cfg.DebugLevel == DebugMode.Simulate) return true; + + if (msrmntState == MsrmntState.Busy || + msrmntState == MsrmntState.Busy1 || + msrmntState == MsrmntState.Busy2 || + msrmntState == MsrmntState.Busy3) + { + log.WarnFormat("{0} - GetImmediateMassMeasurement() returns false ... measurementState == {1}", name, msrmntState.ToString()); + return false; + } + + msrmntState = (MsrmntState)((int)MsrmntState.Busy + scaleId); + stringBuilder.Clear(); + string serialData = string.Format("AR WT0{0}01\r\n", scaleId); + serialPort.Write(serialData); + log.InfoFormat("{0} - GetImmediateMassMeasurement() ... \"{1}\" sent", name, serialData); + return true; + } + /// /// Parse characters received from the serial port /// @@ -136,109 +187,72 @@ namespace TBF.BenchControl.MettlerToledo.Multi if (balanceCfg.IdNr != 1) return; - log.Debug("RunDevice()"); + log.DebugFormat("{0} - RunDevice()", Name); + + /// + /// Communication runs only when the state is MsrmntState.Busy# + /// + if (msrmntState != MsrmntState.Busy1 && + msrmntState != MsrmntState.Busy2 && + msrmntState != MsrmntState.Busy3) + { + return; + } string justReceived = serialPort.ReadExisting(); if (justReceived != null && justReceived.Length > 0) { - string curBuf = justReceived.ToString(); - log.Debug("RunDevice() received " + curBuf); - StringBuilder hexa = new StringBuilder(); - for (int i = 0; curBuf.Length > i; i++) - { - hexa.Append(((int)curBuf[i]).ToString("X2")); - hexa.Append(" "); - } - log.Debug(hexa.ToString()); + log.DebugFormat("RunDevice() received {0}", justReceived); stringBuilder.Append(justReceived); } string currentBuffer = stringBuilder.ToString(); - stringBuilder.Clear(); - int eolPos = currentBuffer.IndexOf('\r'); - if (eolPos >= 0 && currentBuffer.Length > eolPos + 33) + int eolPos = currentBuffer.IndexOf("\r\n"); + if (eolPos >= 0) { + log.InfoFormat("eolPos = {0}", eolPos); + msrmntTimeStamp = StateMachine.Time; + int balanceIdNr = (int)msrmntState - (int)MsrmntState.Busy; - /// Get part of theh string before EOL - int balanceIdNr = currentBuffer[eolPos + 1]; - string received = currentBuffer.Substring(eolPos + 2, 15); + /// Get part of the string before EOL + string received = currentBuffer.Substring(0, eolPos); - while (true) + /// Put the rest back to the string builder + stringBuilder.Clear(); + if (currentBuffer.Length > eolPos + 2) { - string tmp = received.Replace(" ", " "); - if (tmp.Length == received.Length) break; - received = tmp; + stringBuilder.Append(currentBuffer.Substring(eolPos + 2)); } - string[] fields = received.Split(new char[] { ' ' }); - - if (fields.Length == 3 && balanceIdNr >= 1 && balanceIdNr <= nextBalanceIdx) + if (received.Length == 19 && received.Substring(0, 6).Equals("AR A \"")) { - int code; - float tmpMass; - if (int.TryParse(fields[0], out code) && - (code >= 0 || code == -8) && - float.TryParse(fields[1], - NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, - CultureInfo.InvariantCulture, - out tmpMass)) + string weightStr = received.Substring(6, 12); + while ((weightStr[0] == ' ') && (weightStr.Length > 1)) { - Masses[balanceIdNr - 1] = tmpMass * Balances[balanceIdNr - 1].Resolution; - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Valid; - log.InfoFormat("Balance({2}) Valid response=\"{0}\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr); + weightStr = weightStr.Substring(1, weightStr.Length - 1); + } + + float weight = 0; + if (Utils.TryParseSFloat(weightStr, out weight)) + { + Masses[balanceIdNr - 1] = weight * Balances[balanceIdNr - 1].Resolution; + log.InfoFormat("Balance({0}) Valid response=\"{1}\", Mass = {2}kg", balanceIdNr, received, Masses[balanceIdNr - 1]); + + msrmntState = MsrmntState.Valid; + } + else + { + log.WarnFormat("Balance({0}) Failed response=\"{1}\", Error 1 !!!", balanceIdNr, received); + msrmntState = MsrmntState.Failed; } - else - { - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Busy; - log.InfoFormat("Balance({2}) Busy response=\"{0}\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr); - } - } - else - { - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed; - log.WarnFormat("Balance({2}) Failed response=\"{0}\", Unexpected error !!!", received, balanceIdNr); } - - /// Get part of theh string before EOL - balanceIdNr = currentBuffer[eolPos + 18]; - received = currentBuffer.Substring(eolPos + 19, 15); - - while (true) - { - string tmp = received.Replace(" ", " "); - if (tmp.Length == received.Length) break; - received = tmp; - } - - fields = received.Split(new char[] { ' ' }); - - if (fields.Length == 3 && balanceIdNr >= 1 && balanceIdNr <= nextBalanceIdx) - { - int code; - float tmpMass; - if (int.TryParse(fields[0], out code) && - (code >= 0 || code == -8) && - float.TryParse(fields[1], - NumberStyles.AllowDecimalPoint | NumberStyles.AllowLeadingSign, - CultureInfo.InvariantCulture, - out tmpMass)) - { - Masses[balanceIdNr - 1] = tmpMass * Balances[balanceIdNr - 1].Resolution; - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Valid; - log.InfoFormat("Balance({2}) Valid response=\"{0}\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr); - } - else - { - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Busy; - log.InfoFormat("Balance({2}) Busy response=\"{0}\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr); - } - } else { - Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed; - log.WarnFormat("Balance({2}) Failed response=\"{0}\", Unexpected error !!!", received, balanceIdNr); - } + //Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed; + log.WarnFormat("Balance({0}) Failed response=\"{1}\", Error 2 !!!", balanceIdNr, received); + msrmntState = MsrmntState.Failed; + } } } diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadMassOp.cs b/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadMassOp.cs index edfbf7358..e915a5911 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadMassOp.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadMassOp.cs @@ -13,6 +13,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi private static readonly ILog log = LogManager.GetLogger(typeof(ReadMassOp)); public override string ToString() { return string.Format("ReadMassOp(.,.)"); } + bool started; bool done; /// Set by the constructor @@ -38,7 +39,9 @@ namespace TBF.BenchControl.MettlerToledo.Multi /// Start this operation public void Start() { + started = false; done = false; + started = BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name); } /// Run this operation @@ -49,16 +52,21 @@ namespace TBF.BenchControl.MettlerToledo.Multi /// public Event Run() { - if (balanceDev.MsrmntState == MsrmntState.Valid) + if (!started) + { + started = BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name); + return Event.Busy; + } + else if (done) + { + return Event.BalanceDone; /// Mass has already been read (at least once) + } + else if (balanceDev.MsrmntState == MsrmntState.Valid) { result.Val = balanceDev.Mass; - done = true; log.InfoFormat("ReadMassOp.Run() ... mass={0} ... returning Event.BalanceDone", balanceDev.Mass); - return Event.BalanceDone; /// Mass read OK - } - else if (done) - { - return Event.BalanceDone; /// Mass has already been read (at least once) + done = true; + return Event.BalanceDone; /// Mass read OK } else { diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadStableMassOp.cs b/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadStableMassOp.cs index 11f1c18b6..4f31cf0c0 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadStableMassOp.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Multi/ReadStableMassOp.cs @@ -25,6 +25,8 @@ namespace TBF.BenchControl.MettlerToledo.Multi int totalReadingsCount; FloatBox result; + bool started; + /// /// Events: BalanceDone, Error /// @@ -44,11 +46,14 @@ namespace TBF.BenchControl.MettlerToledo.Multi log.Debug(this.ToString()); } + /// Start this operation public void Start() { + started = false; currentReadingsCount = 0; massReadings = new float[totalReadingsCount]; + started = BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name); } /// Run this operation @@ -82,6 +87,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi } } + BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name); return Event.None; } diff --git a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs index 8f8e7845e..a9b535005 100644 --- a/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs +++ b/TestBenchFramework/BenchControl/MettlerToledo/Standard/BalanceDev.cs @@ -238,8 +238,7 @@ namespace TBF.BenchControl.MettlerToledo.Standard { if (balanceCfg.DebugLevel == DebugMode.Simulate) { - mass = TestBenchSim.GetSimMass(balanceNr); - Masses[balanceNr] = mass; + Masses[balanceNr] = TestBenchSim.GetSimMass(balanceNr); msrmntState = MsrmntState.Valid; msrmntTimeStamp = StateMachine.Time; return; @@ -262,7 +261,7 @@ namespace TBF.BenchControl.MettlerToledo.Standard { msrmntTimeStamp = StateMachine.Time; - /// Get part of theh string before EOL + /// Get part of the string before EOL string received = currentBuffer.Substring(0, eolPos); /// Put the rest back to the string builder