From e63f706f41f7c6e7018e0f5a46c4253651a8e063 Mon Sep 17 00:00:00 2001 From: Marek Frniak Date: Tue, 15 Sep 2026 20:21:54 +0200 Subject: [PATCH] : Handle scale underload before mass measurement, increase revision to 3.9.3146.120 Cause: - Starting measurement overwrote Underload with Busy. - IND400 then returned S I, causing repeated measurements without zeroing. Solution: 1. Check underload before measurement in both Mettler Toledo implementations. 2. Zero the scale first and resume measurement after successful zeroing. 3. Return an error if zeroing fails or times out. 4. Preserve existing SICS and ID1 commands and response handling. 5. Increased revision to 3.9.3146.120. --- TBF/Properties/AssemblyInfo.cs | 4 +- .../Standard/ReadStableMassOp.cs | 63 +++++++++++------- .../Scales/MettlerToledo/ReadStableMassOp.cs | 65 +++++++++++-------- 3 files changed, 79 insertions(+), 53 deletions(-) diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 12cace187..7c19c9359 100644 --- a/TBF/Properties/AssemblyInfo.cs +++ b/TBF/Properties/AssemblyInfo.cs @@ -32,5 +32,5 @@ using System.Runtime.InteropServices; // Build Number // Revision // -[assembly: AssemblyVersion("3.9.3146.117")] -[assembly: AssemblyFileVersion("3.9.3146.117")] +[assembly: AssemblyVersion("3.9.3146.120")] +[assembly: AssemblyFileVersion("3.9.3146.120")] diff --git a/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs b/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs index 2e6c950eb..963666c80 100644 --- a/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs +++ b/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs @@ -79,6 +79,17 @@ namespace TBF.Rig.MettlerToledo.Standard /// void StartMeasurement() { + if (scale.MsrmntState == MsrmntState.Underload) + { + log.Warn("ReadStableMassOp ... underload before measurement, zeroing scale"); + currentReadingsCount = 0; + Array.Clear(massReadings, 0, massReadings.Length); + Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length); + zeroingAfterUnderload = true; + scale.SendZeroWhenStableCmd(); + return; + } + if (method == MassMethod.Scale) scale.SendStableMeasurementCmd(); else @@ -95,9 +106,9 @@ namespace TBF.Rig.MettlerToledo.Standard if (delayBefore == 0 && scale.Activity == Activity.Idle) { - StartMeasurement(); - scale.Activity = Activity.RunningOperation; opState = OpState.MassMeasurement; + scale.Activity = Activity.RunningOperation; + StartMeasurement(); } else { @@ -117,9 +128,9 @@ namespace TBF.Rig.MettlerToledo.Standard { if (StateMachine.Time >= startTime + delayBefore && scale.Activity == Activity.Idle) { - StartMeasurement(); - scale.Activity = Activity.RunningOperation; opState = OpState.MassMeasurement; + scale.Activity = Activity.RunningOperation; + StartMeasurement(); } return Event.None; @@ -132,6 +143,29 @@ namespace TBF.Rig.MettlerToledo.Standard return Event.ScaleDone; } + // A zero response is not a mass sample. Never fall through to measurement + // retries after failed zeroing, or the next mass could look like zero success. + if (zeroingAfterUnderload) + { + if (scale.MsrmntState == MsrmntState.Busy) + { + // Give stable zeroing its own timeout, independent of the mass method. + if (scale.MsrmntTime < 60) return Event.None; + log.Error("ReadStableMassOp ... zeroing after underload timed out"); + scale.MsrmntState = MsrmntState.Failed; + return Event.Error; + } + if (scale.MsrmntState != MsrmntState.Valid) + { + log.ErrorFormat("ReadStableMassOp ... zeroing after underload failed: {0}", scale.MsrmntState); + return Event.Error; + } + log.Info("ReadStableMassOp ... zeroing after underload completed, restarting measurement"); + zeroingAfterUnderload = false; + StartMeasurement(); + return Event.None; + } + if (scale.MsrmntState == MsrmntState.Busy) { /// Measurement is in progress - resend command if timeout occurs @@ -141,28 +175,7 @@ namespace TBF.Rig.MettlerToledo.Standard if (scale.MsrmntState == MsrmntState.Underload) { - log.WarnFormat( - "ReadStableMassOp.Run() ... scale underload detected, zeroing scale"); - - currentReadingsCount = 0; - Array.Clear(massReadings, 0, massReadings.Length); - Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length); - - zeroingAfterUnderload = true; - scale.SendZeroWhenStableCmd(); - scale.Activity = Activity.RunningOperation; - - return Event.None; - } - - if (zeroingAfterUnderload && scale.MsrmntState == MsrmntState.Valid) - { - log.InfoFormat( - "ReadStableMassOp.Run() ... scale zeroing after underload completed, restarting measurement"); - - zeroingAfterUnderload = false; StartMeasurement(); - return Event.None; } diff --git a/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs b/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs index 739fe6515..24a711c37 100644 --- a/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs +++ b/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs @@ -78,6 +78,17 @@ namespace TBF.Rig.Scales.MettlerToledo /// void StartMeasurement() { + if (scale.MsrmntState == MsrmntState.Underload) + { + log.Warn("ReadStableMassOp ... underload before measurement, zeroing scale"); + currentReadingsCount = 0; + Array.Clear(massReadings, 0, massReadings.Length); + Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length); + opState = OpState.ZeroingAfterUnderload; + scale.SendZeroWhenStableCmd(); + return; + } + if (method == MassMethod.Scale) scale.SendStableMeasurementCmd(); else @@ -93,9 +104,9 @@ namespace TBF.Rig.Scales.MettlerToledo if (delayBefore == 0 && scale.Activity == Activity.Idle) { - StartMeasurement(); - scale.Activity = Activity.RunningOperation; opState = OpState.MassMeasurement; + scale.Activity = Activity.RunningOperation; + StartMeasurement(); } else { @@ -115,9 +126,9 @@ namespace TBF.Rig.Scales.MettlerToledo { if (StateMachine.Time >= startTime + delayBefore && scale.Activity == Activity.Idle) { - StartMeasurement(); - scale.Activity = Activity.RunningOperation; opState = OpState.MassMeasurement; + scale.Activity = Activity.RunningOperation; + StartMeasurement(); } if (scale.DebugLevel == DebugMode.Simulate) @@ -143,15 +154,35 @@ namespace TBF.Rig.Scales.MettlerToledo return Event.ScaleDone; } + // A zero response is not a mass sample. Never fall through to measurement + // retries after failed zeroing, or the next mass could look like zero success. + if (opState == OpState.ZeroingAfterUnderload) + { + if (scale.MsrmntState == MsrmntState.Busy) + { + // Give stable zeroing its own timeout, independent of the mass method. + if (scale.MsrmntTime < 60) return Event.None; + log.Error("ReadStableMassOp ... zeroing after underload timed out"); + scale.MsrmntState = MsrmntState.Failed; + return Event.Error; + } + if (scale.MsrmntState != MsrmntState.Valid) + { + log.ErrorFormat("ReadStableMassOp ... zeroing after underload failed: {0}", scale.MsrmntState); + return Event.Error; + } + log.Info("ReadStableMassOp ... zeroing after underload completed, restarting measurement"); + opState = OpState.MassMeasurement; + StartMeasurement(); + return Event.None; + } + if (scale.MsrmntState == MsrmntState.Busy) { /// The command is still being processed - resend it after timeout. if (scale.MsrmntTime >= timeout) { - if (opState == OpState.ZeroingAfterUnderload) - scale.SendZeroWhenStableCmd(); - else - StartMeasurement(); + StartMeasurement(); } return Event.None; @@ -159,25 +190,7 @@ namespace TBF.Rig.Scales.MettlerToledo if (scale.MsrmntState == MsrmntState.Underload) { - log.Warn("ReadStableMassOp.Run() ... scale underload detected, zeroing scale"); - - currentReadingsCount = 0; - Array.Clear(massReadings, 0, massReadings.Length); - Array.Clear(sortedMassReadings, 0, sortedMassReadings.Length); - - opState = OpState.ZeroingAfterUnderload; - scale.SendZeroWhenStableCmd(); - - return Event.None; - } - - if (opState == OpState.ZeroingAfterUnderload && scale.MsrmntState == MsrmntState.Valid) - { - log.Info("ReadStableMassOp.Run() ... scale zeroing completed, restarting mass measurement"); - - opState = OpState.MassMeasurement; StartMeasurement(); - return Event.None; }