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
This commit is contained in:
Marek Frniak 2026-07-13 13:56:26 +02:00
parent 38d28599ad
commit 0075362f92
9 changed files with 109 additions and 19 deletions

View File

@ -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")]

View File

@ -10,6 +10,7 @@ namespace TBF.Rig
{
Valid,
Overload,
Underload,
Failed,
Busy,
Busy1, ///
@ -86,6 +87,7 @@ namespace TBF.Rig
AmbientDone,
ScaleDone,
ScaleUnderload,
ScaleOverload,
ScaleTimeout,
PressureDone,

View File

@ -34,6 +34,8 @@ namespace TBF.Rig.MettlerToledo.Standard
bool measurementCompleted;
int timeout;
bool zeroingAfterUnderload;
/// <summary>
/// Events: BalanceDone, Error
/// </summary>
@ -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,6 +139,33 @@ namespace TBF.Rig.MettlerToledo.Standard
return Event.None; /// Wait for a mass measurement
}
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

View File

@ -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;

View File

@ -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;

View File

@ -68,6 +68,7 @@ namespace TBF.Rig.Scales.MettlerToledo
{
WaitingBeforeMeasurment,
MassMeasurement,
ZeroingAfterUnderload,
}
OpState opState;
@ -144,9 +145,40 @@ namespace TBF.Rig.Scales.MettlerToledo
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
/// The command is still being processed - resend it after timeout.
if (scale.MsrmntTime >= timeout)
{
if (opState == OpState.ZeroingAfterUnderload)
scale.SendZeroWhenStableCmd();
else
StartMeasurement();
}
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)

View File

@ -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] == "+") ||

View File

@ -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;

View File

@ -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;