Mettler-Toledo Multi protocol change as in v.2.0.195 (Badger), Immediate meas. works, TODO: stable meas.
This commit is contained in:
parent
0fdcbffcae
commit
adb37826a5
@ -12,6 +12,9 @@ namespace TBF.BenchControl
|
||||
Overload,
|
||||
Failed,
|
||||
Busy,
|
||||
Busy1, ///
|
||||
Busy2, /// Used by Mettler-Toledo Multi to distinguish which scale was queried
|
||||
Busy3, ///
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -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;
|
||||
|
||||
/// <summary>
|
||||
/// 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; } }
|
||||
|
||||
/// <summary>The state of the mass measurement</summary>
|
||||
public MsrmntState MsrmntState { get { return msrmntState; } }
|
||||
protected MsrmntState msrmntState;
|
||||
protected static MsrmntState msrmntState;
|
||||
|
||||
/// <summary>The mass after StartMassMeasurement() when MsrmntState == MsrmntState.Valid</summary>
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get a stable mass measurement
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Get an immediate mass measurement
|
||||
/// </summary>
|
||||
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;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Parse characters received from the serial port
|
||||
/// </summary>
|
||||
@ -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}<cr>\", 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}<cr>\", Mass = {2}kg", balanceIdNr, received, Masses[balanceIdNr - 1]);
|
||||
|
||||
msrmntState = MsrmntState.Valid;
|
||||
}
|
||||
else
|
||||
{
|
||||
log.WarnFormat("Balance({0}) Failed response=\"{1}<cr>\", Error 1 !!!", balanceIdNr, received);
|
||||
msrmntState = MsrmntState.Failed;
|
||||
}
|
||||
else
|
||||
{
|
||||
Balances[balanceIdNr - 1].msrmntState = MsrmntState.Busy;
|
||||
log.InfoFormat("Balance({2}) Busy response=\"{0}<cr>\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed;
|
||||
log.WarnFormat("Balance({2}) Failed response=\"{0}<cr>\", 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}<cr>\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr);
|
||||
}
|
||||
else
|
||||
{
|
||||
Balances[balanceIdNr - 1].msrmntState = MsrmntState.Busy;
|
||||
log.InfoFormat("Balance({2}) Busy response=\"{0}<cr>\", Mass = {1}kg", received, Masses[balanceIdNr - 1], balanceIdNr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed;
|
||||
log.WarnFormat("Balance({2}) Failed response=\"{0}<cr>\", Unexpected error !!!", received, balanceIdNr);
|
||||
}
|
||||
//Balances[balanceIdNr - 1].msrmntState = MsrmntState.Failed;
|
||||
log.WarnFormat("Balance({0}) Failed response=\"{1}<cr>\", Error 2 !!!", balanceIdNr, received);
|
||||
msrmntState = MsrmntState.Failed;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
started = false;
|
||||
done = false;
|
||||
started = BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
@ -49,16 +52,21 @@ namespace TBF.BenchControl.MettlerToledo.Multi
|
||||
/// </returns>
|
||||
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
|
||||
{
|
||||
|
||||
@ -25,6 +25,8 @@ namespace TBF.BenchControl.MettlerToledo.Multi
|
||||
int totalReadingsCount;
|
||||
FloatBox result;
|
||||
|
||||
bool started;
|
||||
|
||||
/// <summary>
|
||||
/// Events: BalanceDone, Error
|
||||
/// </summary>
|
||||
@ -44,11 +46,14 @@ namespace TBF.BenchControl.MettlerToledo.Multi
|
||||
log.Debug(this.ToString());
|
||||
}
|
||||
|
||||
|
||||
/// <summary>Start this operation</summary>
|
||||
public void Start()
|
||||
{
|
||||
started = false;
|
||||
currentReadingsCount = 0;
|
||||
massReadings = new float[totalReadingsCount];
|
||||
started = BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name);
|
||||
}
|
||||
|
||||
/// <summary>Run this operation</summary>
|
||||
@ -82,6 +87,7 @@ namespace TBF.BenchControl.MettlerToledo.Multi
|
||||
}
|
||||
}
|
||||
|
||||
BalanceDev.GetImmediateMassMeasurement(balanceDev.IdNr, balanceDev.Name);
|
||||
return Event.None;
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user