diff --git a/TBF/BenchControl/Elde/ControlBoardDev.cs b/TBF/BenchControl/Elde/ControlBoardDev.cs
index 65fc1e231..52e5e2878 100644
--- a/TBF/BenchControl/Elde/ControlBoardDev.cs
+++ b/TBF/BenchControl/Elde/ControlBoardDev.cs
@@ -222,34 +222,27 @@ namespace TBF.BenchControl.Elde
}
- static bool doMassesVolumesLog = true;
- ///
public void UpdateWeights()
{
+ /// Mettler-Toledo scales
for (int i = 0; i < MettlerToledo.Standard.BalanceDev.BalancesCount; i++)
{
- double mass = MettlerToledo.Standard.BalanceDev.Masses[i];
- controlCom.SetWeight(i, mass);
- if (doMassesVolumesLog) log.DebugFormat("UpdateWeights() : ix={0} mass={1}", i, mass);
+ controlCom.SetWeight(i, MettlerToledo.Standard.BalanceDev.Masses[i]);
}
+ /// Mettler-Toledo-multi scales (Badger Brno, ...)
for (int i = 0; i < MettlerToledo.Multi.BalanceDev.BalancesCount; i++)
{
- double mass = MettlerToledo.Multi.BalanceDev.Masses[i];
- controlCom.SetWeight(i, mass);
- if (doMassesVolumesLog) log.DebugFormat("UpdateWeights() : ix={0} mass={1}", i, mass);
+ controlCom.SetWeight(i, MettlerToledo.Multi.BalanceDev.Masses[i]);
}
+ /// Tanks (CEVAK, ...)
int firstTankIx = Math.Max(MettlerToledo.Standard.BalanceDev.BalancesCount, MettlerToledo.Multi.BalanceDev.BalancesCount);
for (int i = 0; i < Various.TankWithLevelMsrmnt.Tank.TanksCount; i++)
{
- double volume = Various.TankWithLevelMsrmnt.Tank.Tanks[i].Volume;
- controlCom.SetWeight(firstTankIx + i, volume);
- if (doMassesVolumesLog) log.DebugFormat("UpdateWeights() : ix={0}, volume={1}", firstTankIx + i, volume);
+ controlCom.SetWeight(firstTankIx + i, Various.TankWithLevelMsrmnt.Tank.Tanks[i].Volume);
}
-
- //doMassesVolumesLog = false; /// When this line is uncommented logging is done only once on startup
}
diff --git a/TBF/BenchControl/Hart/Nivotrack/Nivotrack.cs b/TBF/BenchControl/Hart/Nivotrack/Nivotrack.cs
index daf8d738f..cdd72f98e 100644
--- a/TBF/BenchControl/Hart/Nivotrack/Nivotrack.cs
+++ b/TBF/BenchControl/Hart/Nivotrack/Nivotrack.cs
@@ -3,11 +3,6 @@
///
using System;
using System.Collections.Generic;
-using System.Diagnostics;
-using System.Globalization;
-using System.IO.Ports;
-using System.Text;
-using System.Threading;
using Config.Entities;
using log4net;
using TBF.BenchControl.Generic;
@@ -22,20 +17,30 @@ namespace TBF.BenchControl.Hart.Nivotrack
///
public class Nivotrack : ComponentBase, IDevice, ILevelMeter, IOperation
{
+ const int StableReadingsCount = 9;
+
private static readonly ILog log = LogManager.GetLogger(typeof(Nivotrack));
public override string ToString() { return string.Format("{0}({1})", Cfg.Name, Cfg.ToString(-1)); }
- private readonly NivotrackCfg nivotrackCfg;
- private readonly IHart hart;
+ readonly NivotrackCfg nivotrackCfg;
+ readonly IHart hart;
- bool readingValid;
- double rawLevel_mm;
public double Level { get { return ReadLevel(); } }
- DoubleBox levelBox;
- double sdev;
+ double rawLevel_mm;
+ bool isRawLevelValid;
- enum CurrentOp
+ /// For stable measurement calculation
+ double maxSDev;
+ double[] levelReadings;
+ double[] sortedLevelReadings;
+ int currentReadingsCount;
+
+ bool measurementCompleted; /// stableMeasurementCompleted
+
+ DoubleBox levelBox;
+ ///
+ enum CurrentOp
{
None,
ReadLevel,
@@ -60,6 +65,9 @@ namespace TBF.BenchControl.Hart.Nivotrack
hart = (IHart)TbfComponents.FindComponent(cfg.ParentName, components);
if (hart == null) throw new Exception("Cannot find " + Name + " parent");
+ levelReadings = new double[StableReadingsCount];
+ sortedLevelReadings = new double[StableReadingsCount];
+
log.Debug(this.ToString());
}
@@ -68,7 +76,7 @@ namespace TBF.BenchControl.Hart.Nivotrack
if (nivotrackCfg.DebugLevel == DebugMode.Simulate) return;
rawLevel_mm = 0;
- readingValid = false;
+ isRawLevelValid = false;
}
@@ -122,11 +130,8 @@ namespace TBF.BenchControl.Hart.Nivotrack
byte unitsID = data[6];
byte[] floatData = new byte[] { data[10], data[9], data[8], data[7] };
rawLevel_mm = System.BitConverter.ToSingle(floatData, 0);
- readingValid = true;
-
- string msg = string.Format("{0} : Received water level = {1} mm, State = {2}", Name, rawLevel_mm, state.ToString("X4"));
- Debug.WriteLine(msg);
- log.Info(msg);
+ isRawLevelValid = true;
+ log.InfoFormat("{0} : Received water level = {1} mm, State = {2}", Name, rawLevel_mm, state.ToString("X4"));
}
else if ((data.Length == 7) && (data[0] == (byte)Mark.ShortFrameSlave2Master)
&& (data[2] == (byte)Cmd.ReadPrimaryVar)
@@ -136,9 +141,8 @@ namespace TBF.BenchControl.Hart.Nivotrack
/// A frame with a status only
///
ushort state = (ushort)(256 * data[4] + data[5]);
- string msg = string.Format("{0} : State = {1}", Name, state.ToString("X4"));
- Debug.WriteLine(msg);
- log.Info(msg);
+ isRawLevelValid = false;
+ log.InfoFormat("{0} : State = {1}", Name, state.ToString("X4"));
}
}
}
@@ -176,21 +180,31 @@ namespace TBF.BenchControl.Hart.Nivotrack
}
/// Reference to the operation
- public IOperation ReadStableLevelOp(ref DoubleBox levelBox, double sdev)
+ public IOperation ReadStableLevelOp(ref DoubleBox levelBox, double maxSDev)
{
if (currentOp != CurrentOp.None) throw new Exception("Sequence error");
this.levelBox = levelBox;
- this.sdev = sdev;
+ this.maxSDev = maxSDev;
currentOp = CurrentOp.ReadStableLevel;
+
return this;
}
/// Start this operation
public void Start()
{
- if (readingValid && (levelBox != null))
+ if (currentOp == CurrentOp.ReadLevel)
{
- levelBox.Val = ReadLevel();
+ if (isRawLevelValid && (levelBox != null)) levelBox.Val = ReadLevel();
+ }
+ else if (currentOp == CurrentOp.ReadStableLevel)
+ {
+ currentReadingsCount = 0;
+ measurementCompleted = false;
+ if (isRawLevelValid)
+ {
+ levelReadings[currentReadingsCount++] = ReadLevel();
+ }
}
}
@@ -198,16 +212,82 @@ namespace TBF.BenchControl.Hart.Nivotrack
/// Event.ResultsPrinted
public Event Run()
{
- if (readingValid && (levelBox != null))
- {
- levelBox.Val = ReadLevel();
- return Event.LevelDone;
- }
- else
- {
- return Event.Busy;
- }
- }
+ if (measurementCompleted)
+ {
+ if ((currentOp == CurrentOp.ReadLevel) && (levelBox != null)) levelBox.Val = ReadLevel();
+ return Event.LevelDone;
+ }
+
+ if ((currentOp == CurrentOp.ReadLevel) && isRawLevelValid)
+ {
+ if (levelBox != null) levelBox.Val = ReadLevel();
+ measurementCompleted = true;
+ return Event.LevelDone;
+ }
+ else if ((currentOp == CurrentOp.ReadStableLevel) && isRawLevelValid)
+ {
+ ///
+ /// Read new level and put it into a FIFO buffer
+ ///
+ if (currentReadingsCount < StableReadingsCount)
+ {
+ levelReadings[currentReadingsCount++] = ReadLevel();
+ }
+ else
+ {
+ /// Shift data in the (already full) buffer, save the mass into the last buffer item
+ for (int i = 1; i < StableReadingsCount; i++)
+ {
+ levelReadings[i - 1] = levelReadings[i];
+ }
+ levelReadings[StableReadingsCount - 1] = ReadLevel();
+ }
+
+ ///
+ /// Evaluate reading stability
+ ///
+ if (currentReadingsCount >= StableReadingsCount)
+ {
+ Array.Copy(levelReadings, sortedLevelReadings, StableReadingsCount);
+ Array.Sort(sortedLevelReadings);
+
+ if (true)
+ {
+ /// Spread of values (except of the largest and the smalles value) must be <= maxSDev
+
+ if ((sortedLevelReadings[StableReadingsCount - 2] - sortedLevelReadings[1]) <= maxSDev)
+ {
+ double massSum = 0;
+ for (int i = 1; i < StableReadingsCount - 1; i++) massSum += sortedLevelReadings[i];
+ double ave = massSum / (StableReadingsCount - 2);
+ if (levelBox != null) levelBox.Val = ave;
+ measurementCompleted = true;
+ log.InfoFormat("ReadStableLevelOp.Run() ... valid level={0} ... returning LevelDone", ave);
+ return Event.LevelDone;
+ }
+ }
+ else
+ {
+ /// Standard deviation (except of the largest and the smalles value) must be <= maxSDev
+ double massSum = 0;
+ for (int i = 1; i < StableReadingsCount - 1; i++) massSum += sortedLevelReadings[i];
+ double ave = massSum / (StableReadingsCount - 2);
+ double sdev = 0;
+ for (int i = 1; i < StableReadingsCount - 1; i++) sdev += ((sortedLevelReadings[i] - ave) * (sortedLevelReadings[i] - ave));
+
+ if (Math.Sqrt(sdev / (StableReadingsCount - 2)) <= maxSDev)
+ {
+ if (levelBox != null) levelBox.Val = ave;
+ measurementCompleted = true;
+ log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", ave);
+ return Event.LevelDone;
+ }
+ }
+ }
+ }
+
+ return Event.Busy;
+ }
/// Stop this operation
public void Stop()
diff --git a/TBF/BenchControl/MettlerToledo/Standard/ReadStableMassOp.cs b/TBF/BenchControl/MettlerToledo/Standard/ReadStableMassOp.cs
index 4ef0ef059..3383dc38a 100644
--- a/TBF/BenchControl/MettlerToledo/Standard/ReadStableMassOp.cs
+++ b/TBF/BenchControl/MettlerToledo/Standard/ReadStableMassOp.cs
@@ -23,7 +23,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard
DoubleBox result;
/// Operation specific
- double[] massReadings;
+ double[] massReadings;
+ double[] sortedMassReadings;
int currentReadingsCount;
bool measurementCompleted;
@@ -48,7 +49,8 @@ namespace TBF.BenchControl.MettlerToledo.Standard
this.result = result;
massReadings = new double[totalReadingsCount];
- currentReadingsCount = 0;
+ sortedMassReadings = new double[totalReadingsCount];
+ currentReadingsCount = 0;
measurementCompleted = false;
log.Debug(this.ToString());
@@ -114,17 +116,18 @@ namespace TBF.BenchControl.MettlerToledo.Standard
if (currentReadingsCount >= totalReadingsCount)
{
- Array.Sort(massReadings);
+ Array.Copy(massReadings, sortedMassReadings, totalReadingsCount);
+ Array.Sort(sortedMassReadings);
#if STABLE_MASS_EXTRAS
if (method == Config.Entities.MassMethod.Spread)
{
/// Immediate mass measurement, end condition calculated below
- if ((massReadings[totalReadingsCount - 2] - massReadings[1]) <= maxSpread)
+ if ((sortedMassReadings[totalReadingsCount - 2] - sortedMassReadings[1]) <= maxSpread)
{
double massSum = 0;
- for (int i = 1; i < totalReadingsCount - 1; i++) massSum += massReadings[i];
+ for (int i = 1; i < totalReadingsCount - 1; i++) massSum += sortedMassReadings[i];
result.Val = (massSum / (totalReadingsCount - 2));
log.InfoFormat("ReadStableMassOp.Run() ... valid mass={0} ... returning Event.BalanceDone", result.Val);
@@ -137,10 +140,10 @@ namespace TBF.BenchControl.MettlerToledo.Standard
/// Immediate mass measurement, end condition calculated below
double massSum = 0;
- for (int i = 1; i < totalReadingsCount - 1; i++) massSum += massReadings[i];
+ for (int i = 1; i < totalReadingsCount - 1; i++) massSum += sortedMassReadings[i];
double ave = (massSum / (totalReadingsCount - 2));
double sdev = 0;
- for (int i = 1; i < totalReadingsCount - 1; i++) sdev += ((massReadings[i] - ave) * (massReadings[i] - ave));
+ for (int i = 1; i < totalReadingsCount - 1; i++) sdev += ((sortedMassReadings[i] - ave) * (sortedMassReadings[i] - ave));
if (Math.Sqrt(sdev / (totalReadingsCount - 2)) <= maxSpread)
{
diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs
index f4cc0eee7..8494572c3 100644
--- a/TBF/Properties/AssemblyInfo.cs
+++ b/TBF/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.18.1064.0")]
-[assembly: AssemblyFileVersion("2.18.1064.0")]
+[assembly: AssemblyVersion("2.18.1065.0")]
+[assembly: AssemblyFileVersion("2.18.1065.0")]