From 0075362f92220a825e743d91976467c6f4bf9dfe Mon Sep 17 00:00:00 2001 From: Marek Frniak Date: Mon, 13 Jul 2026 13:56:26 +0200 Subject: [PATCH] Fix - Handle scale underload condition - Added Underload measurement state - Detect underload responses from Mettler Toledo scales - Automatically zero the scale after underload detection - Restart mass measurement after successful zeroing - Prevent zeroing response from being used as a valid measurement - Preserve measurement stability by clearing buffered readings after underload --- TBF/Properties/AssemblyInfo.cs | 4 +- TBF/Rig/Events.cs | 4 +- .../Standard/ReadStableMassOp.cs | 44 ++++++++++++++--- TBF/Rig/MettlerToledo/Standard/TaringOp.cs | 7 +++ TBF/Rig/MettlerToledo/Standard/ZeroOp.cs | 6 +++ .../Scales/MettlerToledo/ReadStableMassOp.cs | 48 +++++++++++++++---- TBF/Rig/Scales/MettlerToledo/Scale.cs | 2 +- TBF/Rig/Scales/MettlerToledo/TaringOp.cs | 7 +++ TBF/Rig/Scales/MettlerToledo/ZeroOp.cs | 6 +++ 9 files changed, 109 insertions(+), 19 deletions(-) diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs index 3c0c127e6..eb3d714a4 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.3069.1")] -[assembly: AssemblyFileVersion("3.9.3069.1")] +[assembly: AssemblyVersion("3.9.3069.8")] +[assembly: AssemblyFileVersion("3.9.3069.8")] diff --git a/TBF/Rig/Events.cs b/TBF/Rig/Events.cs index d616f574e..3b39e0eed 100644 --- a/TBF/Rig/Events.cs +++ b/TBF/Rig/Events.cs @@ -10,7 +10,8 @@ namespace TBF.Rig { Valid, Overload, - Failed, + Underload, + Failed, Busy, Busy1, /// Busy2, /// Used by Mettler-Toledo Multi to distinguish which scale was queried @@ -86,6 +87,7 @@ namespace TBF.Rig AmbientDone, ScaleDone, + ScaleUnderload, ScaleOverload, ScaleTimeout, PressureDone, diff --git a/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs b/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs index 241afbe37..2e6c950eb 100644 --- a/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs +++ b/TBF/Rig/MettlerToledo/Standard/ReadStableMassOp.cs @@ -34,12 +34,14 @@ namespace TBF.Rig.MettlerToledo.Standard bool measurementCompleted; int timeout; - /// - /// Events: BalanceDone, Error - /// - /// Balance device instance - /// Reference to the measured mass in kg - /// Required mass readings count (>= 4) + bool zeroingAfterUnderload; + + /// + /// Events: BalanceDone, Error + /// + /// Balance device instance + /// Reference to the measured mass in kg + /// Required mass readings count (>= 4) /// Maximum spread of measurements in kg (otherwise the measurement continues) /// Method: false = slow (precise), true = fast (immediate) public ReadStableMassOp(GenericDevices.IScale scale, ref DoubleBox result, int delayBefore, MassMethod method, @@ -89,6 +91,7 @@ namespace TBF.Rig.MettlerToledo.Standard startTime = StateMachine.Time; currentReadingsCount = 0; measurementCompleted = false; + zeroingAfterUnderload = false; if (delayBefore == 0 && scale.Activity == Activity.Idle) { @@ -136,7 +139,34 @@ namespace TBF.Rig.MettlerToledo.Standard return Event.None; /// Wait for a mass measurement } - if (scale.MsrmntState == MsrmntState.Valid) + 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; + } + + if (scale.MsrmntState == MsrmntState.Valid) { /// Save the measurement if (currentReadingsCount < totalReadingsCount) diff --git a/TBF/Rig/MettlerToledo/Standard/TaringOp.cs b/TBF/Rig/MettlerToledo/Standard/TaringOp.cs index 4de97e6b4..3374eedd0 100644 --- a/TBF/Rig/MettlerToledo/Standard/TaringOp.cs +++ b/TBF/Rig/MettlerToledo/Standard/TaringOp.cs @@ -78,6 +78,13 @@ namespace TBF.Rig.MettlerToledo.Standard return Event.ScaleOverload; } + if (scale.MsrmntState == MsrmntState.Underload) + { + tara.Val = scale.Capacity; + done = true; + return Event.ScaleUnderload; + } + if (scale.MsrmntState == MsrmntState.Valid) { tara.Val = scale.Mass; diff --git a/TBF/Rig/MettlerToledo/Standard/ZeroOp.cs b/TBF/Rig/MettlerToledo/Standard/ZeroOp.cs index 7519aa5ac..ac2174100 100644 --- a/TBF/Rig/MettlerToledo/Standard/ZeroOp.cs +++ b/TBF/Rig/MettlerToledo/Standard/ZeroOp.cs @@ -68,6 +68,12 @@ namespace TBF.Rig.MettlerToledo.Standard if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy; + if (scale.MsrmntState == MsrmntState.Underload) + { + done = true; + return Event.ScaleUnderload; + } + if (scale.MsrmntState == MsrmntState.Overload) { done = true; diff --git a/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs b/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs index b8882b83c..739fe6515 100644 --- a/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs +++ b/TBF/Rig/Scales/MettlerToledo/ReadStableMassOp.cs @@ -68,6 +68,7 @@ namespace TBF.Rig.Scales.MettlerToledo { WaitingBeforeMeasurment, MassMeasurement, + ZeroingAfterUnderload, } OpState opState; @@ -142,14 +143,45 @@ namespace TBF.Rig.Scales.MettlerToledo return Event.ScaleDone; } - if (scale.MsrmntState == MsrmntState.Busy) - { - /// Measurement is in progress - resend command if timeout occurs - if (scale.MsrmntTime >= timeout) StartMeasurement(); - return Event.None; /// Wait for a mass measurement - } + 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(); + } - if (scale.MsrmntState == MsrmntState.Valid) + return Event.None; + } + + 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; + } + + if (scale.MsrmntState == MsrmntState.Valid) { /// Save the measurement if (currentReadingsCount < totalReadingsCount) @@ -167,7 +199,7 @@ namespace TBF.Rig.Scales.MettlerToledo } } - if (currentReadingsCount >= totalReadingsCount) + if (currentReadingsCount >= totalReadingsCount) { Array.Copy(massReadings, sortedMassReadings, totalReadingsCount); Array.Sort(sortedMassReadings); diff --git a/TBF/Rig/Scales/MettlerToledo/Scale.cs b/TBF/Rig/Scales/MettlerToledo/Scale.cs index 69f7fb786..161a132c6 100644 --- a/TBF/Rig/Scales/MettlerToledo/Scale.cs +++ b/TBF/Rig/Scales/MettlerToledo/Scale.cs @@ -401,7 +401,7 @@ namespace TBF.Rig.Scales.MettlerToledo { /// Invalid value : Scale is in underload range mass = 0; - msrmntState = MsrmntState.Failed; + msrmntState = MsrmntState.Underload; } else if ((proto == Protocol.ID1 && field.Length == 1 && field[0] == "SI+") || (proto == Protocol.SICS && field.Length == 2 && field[0] == "S" && field[1] == "+") || diff --git a/TBF/Rig/Scales/MettlerToledo/TaringOp.cs b/TBF/Rig/Scales/MettlerToledo/TaringOp.cs index b232fddea..b8e66e467 100644 --- a/TBF/Rig/Scales/MettlerToledo/TaringOp.cs +++ b/TBF/Rig/Scales/MettlerToledo/TaringOp.cs @@ -71,6 +71,13 @@ namespace TBF.Rig.Scales.MettlerToledo if (scale.MsrmntState == MsrmntState.Busy) return Event.Busy; + if (scale.MsrmntState == MsrmntState.Underload) + { + tara.Val = scale.Capacity; + done = true; + return Event.ScaleUnderload; + } + if (scale.MsrmntState == MsrmntState.Overload) { tara.Val = scale.Capacity; diff --git a/TBF/Rig/Scales/MettlerToledo/ZeroOp.cs b/TBF/Rig/Scales/MettlerToledo/ZeroOp.cs index 9f17f7e95..880e95bd9 100644 --- a/TBF/Rig/Scales/MettlerToledo/ZeroOp.cs +++ b/TBF/Rig/Scales/MettlerToledo/ZeroOp.cs @@ -74,6 +74,12 @@ namespace TBF.Rig.Scales.MettlerToledo return Event.ScaleOverload; } + if (scale.MsrmntState == MsrmntState.Underload) + { + done = true; + return Event.ScaleUnderload; + } + if (scale.MsrmntState == MsrmntState.Valid) { done = true;