diff --git a/TBF/Rig/TestMethods/iPerlCommunication/common/OptoTelegramRaw.cs b/TBF/Rig/TestMethods/iPerlCommunication/common/OptoTelegramRaw.cs
index 119931a71..debde9c6b 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/common/OptoTelegramRaw.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/common/OptoTelegramRaw.cs
@@ -40,11 +40,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.common
public Int32 EmfRaw; /// Signed EMF from iPerl opto data
public Int16 MagneticFieldRaw;
public Int16 FlowRaw;
- public UInt32 VolumeRaw;
- public Int64 VolumeRawExt;
+ public double VolumeRaw;
+ public double VolumeRawExt;
public Int16 Impedance;
- public UInt32 Timestamp;
- public Int64 TimestampExt;
+ public double Timestamp;
+ public double TimestampExt;
public byte CheckSum;
///
@@ -106,146 +106,148 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.common
///
/// A complete byte array data
/// true = telegram OK, false = telegram NOK
- public bool UpdateFromString(string telegram, int counter, float refFlow, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast, bool isLog = false)
- {
- DateTime = DateTime.Now;
- Counter = counter;
- RefFlow = refFlow;
+ // public bool UpdateFromString(string telegram, int counter, float refFlow, ref Int64 volumeRawExtLast, ref Int64 timestampExtLast, bool isLog = false)
+ // {
+ // DateTime = DateTime.Now;
+ // Counter = counter;
+ // RefFlow = refFlow;
+ //
+ // if ((telegram == null) || (telegram.Length < Length) ||
+ // (telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') ||
+ // (telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') ||
+ // (!isLog && (telegram[40] != '\r' || telegram[41] != '\n')))
+ // {
+ // Flags = OptoTelegramFlags.InvalidTelegram;
+ // return false;
+ // }
+ //
+ // UInt32 uEmfRaw;
+ // bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uEmfRaw);
+ // EmfRaw = (uEmfRaw > 0x7FFFFF) ? ((int)uEmfRaw - 0x1000000) : (int)uEmfRaw;
+ //
+ // bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
+ // bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
+ // bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
+ // bool f5 = Int16.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Impedance);
+ // bool f6 = UInt32.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
+ // bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
+ //
+ // byte calculatedCheckSum = 0;
+ // for (int i = 0; i < Length - 4; i++)
+ // {
+ // calculatedCheckSum += (byte)telegram[i];
+ // }
+ //
+ // bool allOk = f1 && f2 && f3 && f4 && f5 && f6 && f7 && (calculatedCheckSum == CheckSum);
+ //
+ // if (allOk)
+ // {
+ // ///
+ // /// Cope with 'VolumeRaw' overflow
+ // ///
+ // Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
+ // if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
+ // {
+ // VolumeRawExt = volumeRawExtLast = uncorrected;
+ // }
+ // else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
+ // {
+ // VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
+ // }
+ // else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
+ // {
+ // VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
+ // }
+ // else
+ // {
+ // VolumeRawExt = volumeRawExtLast = uncorrected;
+ // }
+ //
+ // ///
+ // /// Cope with 'Timestamp' overflow
+ // ///
+ // uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
+ // if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
+ // {
+ // TimestampExt = timestampExtLast = uncorrected;
+ // }
+ // else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
+ // {
+ // TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
+ // }
+ // else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
+ // {
+ // TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
+ // }
+ // else
+ // {
+ // TimestampExt = timestampExtLast = uncorrected;
+ // }
+ // }
+ //
+ // Flags = allOk ? OptoTelegramFlags.OK : OptoTelegramFlags.InvalidTelegram;
+ //
+ // return allOk;
+ // }
- if ((telegram == null) || (telegram.Length < Length) ||
- (telegram[6] != '\t') || (telegram[11] != '\t') || (telegram[16] != '\t') ||
- (telegram[23] != '\t') || (telegram[28] != '\t') || (telegram[37] != '\t') ||
- (!isLog && (telegram[40] != '\r' || telegram[41] != '\n')))
- {
- Flags = OptoTelegramFlags.InvalidTelegram;
- return false;
- }
+ // -------- TIMESTAMP (seconds) --------
+ const double TS_TICKS_PER_SEC = 4096.0;
+ const double TS_RANGE = (1UL << 32) / TS_TICKS_PER_SEC;
+ //const double TS_HALF = TS_RANGE / 2.0;
- UInt32 uEmfRaw;
- bool f1 = UInt32.TryParse(telegram.Substring(0, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out uEmfRaw);
- EmfRaw = (uEmfRaw > 0x7FFFFF) ? ((int)uEmfRaw - 0x1000000) : (int)uEmfRaw;
-
- bool f2 = Int16.TryParse(telegram.Substring(7, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out MagneticFieldRaw);
- bool f3 = Int16.TryParse(telegram.Substring(12, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out FlowRaw);
- bool f4 = UInt32.TryParse(telegram.Substring(17, 6), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
- bool f5 = Int16.TryParse(telegram.Substring(24, 4), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Impedance);
- bool f6 = UInt32.TryParse(telegram.Substring(29, 8), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
- bool f7 = byte.TryParse(telegram.Substring(38, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
-
- byte calculatedCheckSum = 0;
- for (int i = 0; i < Length - 4; i++)
- {
- calculatedCheckSum += (byte)telegram[i];
- }
-
- bool allOk = f1 && f2 && f3 && f4 && f5 && f6 && f7 && (calculatedCheckSum == CheckSum);
-
- if (allOk)
- {
- ///
- /// Cope with 'VolumeRaw' overflow
- ///
- Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
- if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected;
- }
- else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
- }
- else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
- }
- else
- {
- VolumeRawExt = volumeRawExtLast = uncorrected;
- }
-
- ///
- /// Cope with 'Timestamp' overflow
- ///
- uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
- if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected;
- }
- else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
- }
- else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
- }
- else
- {
- TimestampExt = timestampExtLast = uncorrected;
- }
- }
-
- Flags = allOk ? OptoTelegramFlags.OK : OptoTelegramFlags.InvalidTelegram;
-
- return allOk;
- }
+ // -------- VOLUME (liters) --------
+ const double GAL_TO_LITER = 3.785411784;
+ const double VOL_LITERS_PER_TICK =
+ (4.0 / 1000.0) / GAL_TO_LITER / 2.0;
+ const double VOL_RANGE = (1 << 24) * VOL_LITERS_PER_TICK;
+ //const double VOL_HALF = VOL_RANGE / 2.0;
+
//New IPERL ASIC
- public void UpdateFromSmart(DiagnosticLedState4Data data, int counter, float refFlow,
- ref Int64 volumeRawExtLast, ref Int64 timestampExtLast)
- {
- DateTime = DateTime.Now;
- Counter = counter;
- RefFlow = refFlow;
-
- FlowRaw = data.RawFlow;
- VolumeRaw = data.RawVolume;
- Timestamp = data.AsicTimestamp;
-
-
- ///
- /// Cope with 'VolumeRaw' overflow
- ///
- Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & 0xFFFFFFFFFF000000UL) | VolumeRaw);
- if (Math.Abs(uncorrected - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected;
- }
- else if (Math.Abs(uncorrected + 0x1000000L - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected + 0x1000000L;
- }
- else if (Math.Abs(uncorrected - 0x1000000L - volumeRawExtLast) <= 0x800000L)
- {
- VolumeRawExt = volumeRawExtLast = uncorrected - 0x1000000L;
- }
- else
- {
- VolumeRawExt = volumeRawExtLast = uncorrected;
- }
+ public void UpdateFromSmart(
+ DiagnosticLedState4Data data,
+ int counter,
+ float refFlow,
+ ref double volumeRawExtLast,
+ ref double timestampExtLast)
+ {
+ DateTime = DateTime.Now;
+ Counter = counter;
+ RefFlow = refFlow;
- ///
- /// Cope with 'Timestamp' overflow
- ///
- uncorrected = (Int64)(((UInt64)timestampExtLast & 0xFFFFFFFF00000000UL) | Timestamp);
- if (Math.Abs(uncorrected - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected;
- }
- else if (Math.Abs(uncorrected + 0x100000000L - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected + 0x100000000L;
- }
- else if (Math.Abs(uncorrected - 0x100000000L - timestampExtLast) <= 0x80000000L)
- {
- TimestampExt = timestampExtLast = uncorrected - 0x100000000L;
- }
- else
- {
- TimestampExt = timestampExtLast = uncorrected;
- }
- }
+ FlowRaw = data.RawFlow;
+ VolumeRaw = data.RawVolume;
+ Timestamp = data.AsicTimestamp;
+ // ---------- VOLUME UNWRAP ----------
+ double uncorrected = VolumeRaw;
+
+ if (double.IsNaN(volumeRawExtLast))
+ {
+ VolumeRawExt = volumeRawExtLast = uncorrected;
+ }
+ else
+ {
+ double k = Math.Round((volumeRawExtLast - uncorrected) / VOL_RANGE);
+ VolumeRawExt = volumeRawExtLast = uncorrected + k * VOL_RANGE;
+ }
+
+ // ---------- TIMESTAMP UNWRAP ----------
+ uncorrected = Timestamp;
+
+ if (double.IsNaN(timestampExtLast))
+ {
+ TimestampExt = timestampExtLast = uncorrected;
+ }
+ else
+ {
+ double k = Math.Round((timestampExtLast - uncorrected) / TS_RANGE);
+ TimestampExt = timestampExtLast = uncorrected + k * TS_RANGE;
+ }
+ }
+
+
+
///
/// Alternative to UpdateFromString(...) when data are flushed
///
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedData.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedData.cs
index 1ca1709db..edc2c561e 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedData.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedData.cs
@@ -39,7 +39,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
///
public abstract class DiagnosticLedData
{
-
+ const double GalToLiterConversion = 3.785411784D;
public abstract int GetByteCount();
///
@@ -66,10 +66,35 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
public short RawFlow { get; protected set; }
///
- /// Unsigned 24-bit raw volume accumulation in units of ¼ milliliter per bit.
+ /// Unsigned 24-bit raw volume accumulation in units of ¼ milliliter per bit. it is in Gal * 2
///
- public uint RawVolume { get; protected set; }
-
+ public uint RawVolume1to4 { get; protected set; } // in 1/4 ml Gal * 2
+
+ ///
+ /// Raw volume in liters
+ ///
+ public double RawVolume // in liter
+ {
+ get
+ {
+ double volume = (RawVolume1to4 * 0.00025) ; // convert to liters
+ return volume;
+ }
+ }
+
+ ///
+ /// Raw volume in Gal
+ ///
+ public double RawVolumeInGal // in Gal
+ {
+ get
+ {
+ double volume = (RawVolume1to4 * 4.0) / 1000.0F; // convert to Gal
+ //volume = (volume / GalToLiterConversion) / 2; // convert to liter
+ return volume;
+ }
+ }
+
///
/// Unsigned 16-bit millivolt delta measured on the field drive capacitor.
///
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState1Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState1Data.cs
index 6d9edeee0..651a7637b 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState1Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState1Data.cs
@@ -33,7 +33,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
Adc24 = DiagnosticHex.ParseInt24(f[0]);
FieldStrength = DiagnosticHex.ParseUInt16(f[1]);
RawFlow = DiagnosticHex.ParseInt16(f[2]);
- RawVolume = DiagnosticHex.ParseUInt24(f[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(f[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(f[4]);
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState2Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState2Data.cs
index cda442695..f5364d6ae 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState2Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState2Data.cs
@@ -59,7 +59,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #2 specific ----
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState3Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState3Data.cs
index 09a9f22bf..fb000f1dd 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState3Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState3Data.cs
@@ -59,7 +59,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #3 specific fields ----
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState4Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState4Data.cs
index 76af9df4c..bb0df1c27 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState4Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState4Data.cs
@@ -13,7 +13,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
/// - 0 – xxxxxxsigned 24-bit ADC value
/// - 1 – aaaaunsigned 16-bit Field strength
/// - 2 – yyyysigned 16-bit Raw flow rate (1/4 ml per bit)
- /// - 3 – vvvvvvunsigned 24-bit Raw volume accumulation
+ /// - 3 – vvvvvvunsigned 24 bit raw volume accumulation in ¼ ml per bit
/// - 4 – ccccunsigned 16-bit Capacitor mV delta
/// - 5 – ttttunsigned 16-bit Field calibration
/// - 6 – bbbbbbbbunsigned 32-bit ASIC timestamp
@@ -30,7 +30,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
public sealed class DiagnosticLedState4Data : DiagnosticLedData
{
public ushort FieldCalibration { get; }
- public uint AsicTimestamp { get; }
+
+ ///
+ /// ASIC timestamp in seconds
+ ///
+ public double AsicTimestamp
+ {
+ get { return AsicTimestampTicks / 8192; } //4096.0; }
+ }
+
+ ///
+ /// ASIC timestamp in units of 1 / 4096 seconds.
+ ///
+ public uint AsicTimestampTicks { get; }
public byte FieldDriveTimeUs { get; }
public int MeanFlowRate { get; }
@@ -50,12 +62,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]); //1/4 ml Gal double
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #4 specific ----
FieldCalibration = DiagnosticHex.ParseUInt16(fields[5]);
- AsicTimestamp = DiagnosticHex.ParseUInt32(fields[6]);
+
+ AsicTimestampTicks = DiagnosticHex.ParseUInt32(fields[6]);
FieldDriveTimeUs = DiagnosticHex.ParseByte(fields[7]);
MeanFlowRate = unchecked((int)DiagnosticHex.ParseUInt32(fields[8]));
@@ -71,7 +84,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.
public override string ToString()
{
- return $"DiagnosticLedState4Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}";
+ return $"DiagnosticLedState4Data: Adc24={Adc24}, FieldStrength={FieldStrength}, RawFlow={RawFlow}, RawVolume={RawVolume}, RawVolume1to4 = {RawVolume1to4}, RawVolumeGal={RawVolumeInGal}, CapacitorMv={CapacitorMv}, FieldCalibration={FieldCalibration}, AsicTimestamp={AsicTimestamp}, FieldDriveTimeUs={FieldDriveTimeUs}, MeanFlowRate={MeanFlowRate}, Field1Measurement={Field1Measurement}, Field2Measurement={Field2Measurement}, IntegratorCalibrationPositive={IntegratorCalibrationPositive}, IntegratorCalibrationNegative={IntegratorCalibrationNegative}, AsicState={AsicState}, RawLine={RawLine}";
}
///
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState5Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState5Data.cs
index c541fa74a..a18b926d3 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState5Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState5Data.cs
@@ -69,7 +69,7 @@ public sealed class DiagnosticLedState5Data : DiagnosticLedData
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #5 specific ----
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState6Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState6Data.cs
index d74df8ed8..5303a3417 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState6Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState6Data.cs
@@ -69,7 +69,7 @@ public sealed class DiagnosticLedState6Data : DiagnosticLedData
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #6 specific ----
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState7Data.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState7Data.cs
index 7e203e254..37341581a 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState7Data.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/parserer/DiagnosticLedState7Data.cs
@@ -98,7 +98,7 @@ public sealed class DiagnosticLedState7Data : DiagnosticLedData
Adc24 = DiagnosticHex.ParseInt24(fields[0]);
FieldStrength = DiagnosticHex.ParseUInt16(fields[1]);
RawFlow = DiagnosticHex.ParseInt16(fields[2]);
- RawVolume = DiagnosticHex.ParseUInt24(fields[3]);
+ RawVolume1to4 = DiagnosticHex.ParseUInt24(fields[3]);
CapacitorMv = DiagnosticHex.ParseUInt16(fields[4]);
// ---- State #6 fields ----
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/utils/DiagnostigLedDataByUnit.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/utils/DiagnostigLedDataByUnit.cs
new file mode 100644
index 000000000..960594c52
--- /dev/null
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/diagnosticLed/utils/DiagnostigLedDataByUnit.cs
@@ -0,0 +1,49 @@
+using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.parserer;
+using TBF.Rig.TestMethods.iPerlCommunication.iPerlHead;
+
+namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.utils
+{
+ public class DiagnostigLedDataByUnit
+ {
+ private readonly Common.Unit _unitFlow;
+ private readonly Common.Unit _unitVolume;
+ private readonly DiagnosticLedState4Data _data;
+
+ public DiagnostigLedDataByUnit(Common.Unit unitFlow, Common.Unit unitVolume, DiagnosticLedState4Data data)
+ {
+ this._unitFlow = unitFlow;
+ this._unitVolume = unitVolume;
+ this._data = data;
+ }
+
+ public Common.Unit Unit => _unitVolume;
+ public DiagnosticLedState4Data Data => _data;
+
+ public double RawFlow {
+ get { return UnitVolume(_unitFlow, _data.RawFlow); }
+ }
+
+ public double RawVolume
+ {
+ get { return Common.Units.ConvertFrom(_unitVolume, _data.RawVolume); }
+ }
+
+ public double AsicTimestamp
+ {
+ get { return _data.AsicTimestamp; }
+ }
+
+ public static double UnitVolume(Common.Unit unit, double volume)
+ {
+ return Common.Units.ConvertFrom(unit, volume); /// 1 liter
+ }
+
+ public static uint DeltaTicks(uint oldTicks, uint newTicks)
+ {
+ return newTicks >= oldTicks
+ ? newTicks - oldTicks
+ : uint.MaxValue - oldTicks + newTicks + 1;
+ }
+
+ }
+}
\ No newline at end of file
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/hexLogger/HexFormatter.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/hexLogger/HexFormatter.cs
index 8a9121671..e87448abe 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/hexLogger/HexFormatter.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/C4/hexLogger/HexFormatter.cs
@@ -8,6 +8,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.hexLogger
public static class HexFormatter
{
///
+ /// Byte to hex string.
/// Formats a single byte as 0xNN.
/// Example: 0x0D
///
@@ -17,7 +18,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.C4.hexLogger
}
///
- /// int to byte securely
+ /// int to byte - securely
///
///
///
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/OpthoHeadService.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/OpthoHeadService.cs
index 55859155f..08372dd45 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/OpthoHeadService.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/OpthoHeadService.cs
@@ -4,7 +4,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
{
public class OpthoHeadService
{
- protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
+
}
}
\ No newline at end of file
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/OptoHeadTest.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/OptoHeadTest.cs
index ae462c04d..aa315e93d 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/OptoHeadTest.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/OptoHeadTest.cs
@@ -10,9 +10,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
{
public class OptoHeadTest : IDisposable
{
- protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
+ //protected static readonly ILog rfidDataLogger = LogManager.GetLogger("RfidData");
+ private static readonly ILog log = LogManager.GetLogger(typeof(OptoHeadTest));
- private static SerialDriver serialDriver;
+ private IperlHead iperlHead;
+ private SerialDriver serialDriver;
public static SerialDriver BuildConnection(IperlHead iHead)
{
@@ -27,29 +29,36 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
}
+ public OptoHeadTest(IperlHead iperlHead)
+ {
+ this.iperlHead = iperlHead;
+ }
+
private void CloseConnection()
{
if (serialDriver != null)
serialDriver.CloseConnection();
+ serialDriver = null;
}
- public static string ReadRequest_PCB(ref IperlHead iHead)
+ public string ReadRequest_PCB()
{
- if (iHead.DebugLevel == DebugMode.Simulate)
+ if (iperlHead.DebugLevel == DebugMode.Simulate)
{
return "-OK Simulated response-";
}
try
{
- if (iHead != null)
+ if (iperlHead != null)
{
if (serialDriver == null)
- serialDriver = BuildConnection(iHead);
+ serialDriver = BuildConnection(iperlHead);
RadioService headService = new RadioService(serialDriver);
- string serialNo = headService.ReadRequest_PCB(ref iHead);
+ string serialNo = headService.ReadRequest_PCB(ref iperlHead);
+ log.Info($"PCB Number: {serialNo} on COM{iperlHead.RfidComPortNr} serialDriver: {serialDriver}");
return serialNo;
}
}
@@ -66,12 +75,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- public static bool SetTestMode(ref IperlHead iHead)
+ public bool SetTestMode()
{
- bool activityModeActive = SetActivityMode_Active(iHead);
- bool optActiveMode = SetOptTestMode(ref iHead);
-
+ log.Debug("SetTestMode called for iHead: " + iperlHead.ToString());
+ bool activityModeActive = SetActivityMode_Active();
+ bool optActiveMode = SetOptTestMode();
+ log.Debug("SetTestMode result: optoMod-> " + optActiveMode + " meterModeActive ->" + activityModeActive);
return (optActiveMode && activityModeActive);
}
@@ -80,10 +90,11 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- public static bool SetActiveMode(ref IperlHead iHead)
+ public bool SetActiveMode()
{
- bool optActiveMode = SetOptActiveMode(iHead);
- bool activityModeIdle = SetActivityMode_Idle(iHead);
+ log.Debug("SetActiveMode called for iHead: " + iperlHead.ToString());
+ bool optActiveMode = SetOptActiveMode(iperlHead);
+ bool activityModeIdle = SetActivityMode_Idle();
return (optActiveMode && activityModeIdle);
}
@@ -94,9 +105,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- public static string SetTestMode(ref IperlHead iHead, ref bool isTestModeSuccessful)
+ public string SetTestMode(ref bool isTestModeSuccessful)
{
- if (iHead.DebugLevel == DebugMode.Simulate)
+ if (iperlHead.DebugLevel == DebugMode.Simulate)
{
isTestModeSuccessful = true;
return "-OK Simulated response-";
@@ -104,10 +115,12 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
try
{
- isTestModeSuccessful = SetTestMode(ref iHead);
- return isTestModeSuccessful ? "Set Test Mode - OK" : "Set Test Mode - FAILED";
+ bool testMode = SetTestMode();
+ isTestModeSuccessful = testMode;
+ return testMode ? "Set Test Mode - OK" : "Set Test Mode - FAILED";
}catch (Exception ex)
{
+ log.Error("SetTestMode() - Exception:" + ex.StackTrace);
return "Set Test Mode - Exception";
}
}
@@ -120,18 +133,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- private static bool SetOptTestMode(ref IperlHead iHead)
+ private bool SetOptTestMode()
{
try
{
- if (iHead != null)
+ if (iperlHead != null)
{
if (serialDriver == null)
- serialDriver = BuildConnection(iHead);
+ serialDriver = BuildConnection(iperlHead);
RadioService headService = new RadioService(serialDriver);
- var optTestMode = headService.SetOptTestMode(iHead);
- iHead.ConfigStruct.OpthoStatusMode = optTestMode ? DiagnosticLedState.State4 : DiagnosticLedState.StatusUnknown;
+ bool optTestMode = headService.SetOptTestMode(iperlHead);
+ if (iperlHead.ConfigStruct != null)
+ iperlHead.ConfigStruct.OpthoStatusMode = optTestMode ? DiagnosticLedState.State4 : DiagnosticLedState.StatusUnknown;
return optTestMode;
}
}
@@ -148,9 +162,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- public static string SetActiveMode(ref IperlHead iHead, ref bool isTestModeSuccessful)
+ public string SetActiveMode(ref bool isTestModeSuccessful)
{
- if (iHead.DebugLevel == DebugMode.Simulate)
+ if (iperlHead.DebugLevel == DebugMode.Simulate)
{
isTestModeSuccessful = true;
return "-OK Simulated response-";
@@ -158,8 +172,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
try
{
- isTestModeSuccessful = SetActiveMode(ref iHead);
- return isTestModeSuccessful ? "Set Active Mode - OK" : "Set Active Mode - FAILED";
+ bool activeMode = SetActiveMode();
+ isTestModeSuccessful = activeMode;
+ return activeMode ? "Set Active Mode - OK" : "Set Active Mode - FAILED";
}
catch (Exception ex)
{
@@ -172,7 +187,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- private static bool SetOptActiveMode(IperlHead iHead)
+ private bool SetOptActiveMode(IperlHead iHead)
{
try
{
@@ -180,7 +195,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
{
if (serialDriver == null)
serialDriver = BuildConnection(iHead);
-
+
RadioService headService = new RadioService(serialDriver);
return headService.SetOptActiveMode(iHead);
}
@@ -199,17 +214,18 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- private static bool SetActivityMode_Active(IperlHead iHead)
+ private bool SetActivityMode_Active()
{
try
{
- if (iHead != null)
+ if (iperlHead != null)
{
if (serialDriver == null)
- serialDriver = BuildConnection(iHead);
+ serialDriver = BuildConnection(iperlHead);
+ log.Debug("SetActivityMode_Active called for iHead: " + iperlHead.ToString() + " serialDriver: " + serialDriver);
RadioService headService = new RadioService(serialDriver);
- return headService.SetActivityMode_Active(iHead);
+ return headService.SetActivityMode_Active(iperlHead);
}
}
catch (Exception ex)
@@ -226,17 +242,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- private static bool SetActivityMode_Idle(IperlHead iHead)
+ private bool SetActivityMode_Idle()
{
try
{
- if (iHead != null)
+ if (iperlHead != null)
{
if (serialDriver == null)
- serialDriver = BuildConnection(iHead);
+ serialDriver = BuildConnection(iperlHead);
+
+ log.Debug("SetActivityMode_Idle called for iHead: " + iperlHead.ToString() + " serialDriver: " + serialDriver);
RadioService headService = new RadioService(serialDriver);
- return headService.SetActivityMode_Idle(iHead);
+ return headService.SetActivityMode_Idle(iperlHead);
}
}
catch (Exception ex)
@@ -260,9 +278,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
///
///
///
- public static bool ReadConfiguration(ref IperlHead iHead, DiagnosticLedState ledState )
+ public bool ReadConfiguration(DiagnosticLedState ledState )
{
- if (iHead.DebugLevel == DebugMode.Simulate)
+ if (iperlHead.DebugLevel == DebugMode.Simulate)
{
return true;
}
@@ -270,26 +288,28 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
try
{
- if (iHead != null)
+ if (iperlHead != null)
{
- iHead.ConfigStruct = new ConfigStruct();
+ iperlHead.ConfigStruct = new ConfigStruct();
if (serialDriver == null)
- serialDriver = BuildConnection(iHead);
+ serialDriver = BuildConnection(iperlHead);
RadioService headService = new RadioService(serialDriver);
- iHead.ConfigStruct.PCBNumberString = headService.ReadRequest_PCB(ref iHead);
- iHead.ConfigStruct.StatusMode = headService.GetActivityStatusMode(iHead);
+ iperlHead.ConfigStruct.PCBNumberString = headService.ReadRequest_PCB(ref iperlHead);
+ iperlHead.ConfigStruct.StatusMode = headService.GetActivityStatusMode(iperlHead);
+ iperlHead.ConfigStruct.Unit = headService.GetUnit(iperlHead);
+
if (ledState != DiagnosticLedState.StatusUnknown) // do set
{
- iHead.ConfigStruct.OpthoStatusMode = headService.SetOptoStatusMode(iHead, ledState);
+ iperlHead.ConfigStruct.OpthoStatusMode = headService.SetOptoStatusMode(iperlHead, ledState);
}
else
{
- iHead.ConfigStruct.OpthoStatusMode = DiagnosticLedState.StatusUnknown;
+ iperlHead.ConfigStruct.OpthoStatusMode = DiagnosticLedState.StatusUnknown;
}
- iHead.ConfigStruct.Version = headService.GetVersion(iHead);
+ iperlHead.ConfigStruct.Version = headService.GetVersion(iperlHead);
return true;
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/RadioService.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/RadioService.cs
index b1e3affe2..b08b971b8 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/RadioService.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/RadioService.cs
@@ -1,3 +1,4 @@
+using log4net;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.protocolCommons;
@@ -8,6 +9,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
{
public class RadioService
{
+ private static readonly ILog log = LogManager.GetLogger(typeof(RadioService));
static string okResponse = "Command complete, no errors";
static string errorResponse = "Unable to execute";
@@ -16,6 +18,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
public RadioService(SerialDriver serialDriver)
{
this.serialDriver = serialDriver;
+ log.Debug("RadioService created with serialDriver= " + serialDriver + "");
}
public string ReadRequest_PCB(ref IperlHead iHead)
@@ -97,6 +100,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
+ log.Debug("SetOptoStatusMode isOK: " + decoded.IsOk);
// if is response ok - it set it correctly
if (!decoded.IsOk)
return DiagnosticLedState.StatusUnknown;
@@ -135,6 +139,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
// parse rawData
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
+ log.Debug("GetVersion isOK: " + decoded.IsOk);
if (decoded.IsOk)
{
return decoded.GetAsciiPayload();
@@ -158,7 +163,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
.AddSubCommand(ProtocolStatuses.Active) // Active
.BuildBytes();
- byte[] rawData = serialDriver.SendAndWait(request, 2000);
+ byte[] rawData = serialDriver.SendAndWait(request, 5000);
if (rawData == null)
return false;
@@ -166,6 +171,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
// parse rawData
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
+ log.Debug("SetActivityMode_Active isOK: " + decoded.IsOk);
return decoded.IsOk;
}
@@ -191,6 +197,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
// parse rawData
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
+ log.Debug("SetActivityMode_Idle isOK: " + decoded.IsOk);
return decoded.IsOk;
}
@@ -202,11 +209,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
}
//Set LED to state 4
- byte[] request = new IperlHatFrameBuilder()
- .AddDiagnosticLedState(DiagnosticLedState.State4)
+ var request = new IperlHatFrameBuilder()
+ .RequestResponse(true)
+ .AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState)
+ .AddPayload(DiagnosticLedState.State4)
.BuildBytes();
- byte[] rawData = serialDriver.SendAndWait(request, 1000);
+ byte[] rawData = serialDriver.SendAndWait(request, 5000);
if (rawData == null)
return false;
@@ -214,7 +223,9 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
// parse rawData
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
- return decoded.IsOk;
+ bool isOk = decoded.IsOk;
+ log.Debug("SetOptTestMode isOK: " + isOk);
+ return isOk;
}
@@ -231,11 +242,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
}
//Set LED to state 1
- byte[] request = new IperlHatFrameBuilder()
- .AddDiagnosticLedState(DiagnosticLedState.StateOFF)
+ var request = new IperlHatFrameBuilder()
+ .RequestResponse(true)
+ .AddDeviceCommand(ProtocolDeviceSubCommand.SetDiagnosticLEDState)
+ .AddPayload(DiagnosticLedState.StateOFF)
.BuildBytes();
- byte[] rawData = serialDriver.SendAndWait(request, 2000);
+ byte[] rawData = serialDriver.SendAndWait(request, 5000);
if (rawData == null)
return false;
@@ -243,7 +256,41 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication
// parse rawData
var parser = new IperlHatFrameParser();
IperlHatResponse decoded = parser.Parse(rawData);
+ log.Debug("SetOptActiveMode isOK: " + decoded.IsOk);
return decoded.IsOk;
}
+
+ public string GetUnit(IperlHead iperlHead)
+ {
+ if (!serialDriver.IsOpen())
+ {
+ serialDriver.Open();
+ }
+
+ var request = new IperlHatFrameBuilder()
+ .RequestResponse(true)
+ .AddCommand(ProtocolCommand.ViewFactoryId)
+ .BuildBytes();
+
+
+ byte[] rawData = serialDriver.SendAndWait(request, 10000);
+ if (rawData == null)
+ return null;
+
+ // parse rawData
+ var parser = new IperlHatFrameParser();
+ IperlHatResponse decoded = parser.Parse(rawData);
+ if (decoded.IsOk)
+ {
+ string asciiPayload = decoded.GetAsciiPayload();
+ if (iperlHead.ConfigStruct != null) // store mechanism
+ {
+ iperlHead.ConfigStruct.Unit = asciiPayload;
+ }
+ return asciiPayload;
+ }
+
+ return null;
+ }
}
}
\ No newline at end of file
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/communication/Utils/SerialDriver.cs b/TBF/Rig/TestMethods/iPerlCommunication/communication/Utils/SerialDriver.cs
index fa29f3ea1..2dbf4b93a 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/communication/Utils/SerialDriver.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/communication/Utils/SerialDriver.cs
@@ -4,11 +4,13 @@ using System.Diagnostics;
using System.IO.Ports;
using System.Threading;
using FluentNHibernate.Conventions;
+using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.hexLogger;
namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
{
public class SerialDriver : IDisposable
{
+ readonly log4net.ILog log = log4net.LogManager.GetLogger(typeof(SerialDriver));
public string ErrorMessage { get; private set; }
private List SerialPortReadBuffer = new List();
@@ -110,6 +112,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
ErrorMessage = $"COM error: Can't open {comPort}.";
return false;
}
+
+ log.Debug("SerialDriver opened successfully for port: " + comPort);
}
return true;
}
@@ -172,6 +176,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
_serialPort.DiscardInBuffer();
_binMessages.Clear();
_responseReceived.Reset();
+ SerialPortReadBuffer.Clear();
_isReading = true;
}
@@ -188,7 +193,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
try
{
- Thread.Sleep(5);
+ //Thread.Sleep(5);
if (!SerialPortReadBuffer.IsEmpty())
{
@@ -204,13 +209,13 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
byte readByte = (byte)_serialPort.ReadByte();
//I have START
- if (readByte == TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Start)
+ if (readByte == C4.IperlHatProtocol.IperlHatProtocolConstants.Start)
{
iWordCounter++;
isStart = true;
}
// I have QUESTION
- if (readByte == TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.Question)
+ if (readByte == C4.IperlHatProtocol.IperlHatProtocolConstants.Question)
{
iWordCounter++;
isQuestion = true;
@@ -231,12 +236,16 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
}
//If we have enough bytes
- if (isStart && iLength > 0 && SerialPortReadBuffer.Count >= iLength)
+ if (isStart && iLength > 0
+ && (SerialPortReadBuffer.Count >= iLength ||
+ readByte == C4.IperlHatProtocol.IperlHatProtocolConstants.End
+ )
+ )
{
break;
}
//if we read END
- if (isQuestion && readByte == TestMethods.iPerlCommunication.communication.C4.IperlHatProtocol.IperlHatProtocolConstants.End)
+ if (isQuestion && readByte == C4.IperlHatProtocol.IperlHatProtocolConstants.End)
{
break;
}
@@ -264,11 +273,18 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
if (!IsOpen())
throw new InvalidOperationException("Serial port not open");
+ log.Debug("SendAndWait() - TX: " + HexFormatter.ToHex(data));
PrepareReading();
_serialPort.Write(data, 0, data.Length);
if (!_responseReceived.WaitOne(timeoutMs))
{
+ log.Error("SendAndWait() - Response timeout! Details: " +
+ " SerialPortReadBuffer: " + HexFormatter.ToHex(SerialPortReadBuffer.ToArray()) +
+ " _binMessages" + HexFormatter.ToHex(_binMessages.ToArray()) +
+ "_responseReceived: " + _responseReceived.WaitOne(0)
+ );
+
ErrorMessage = "COM error: response timeout";
return null;
}
@@ -283,5 +299,10 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.communication.Utils
{
CloseConnection();
}
+
+ public override string ToString()
+ {
+ return "SerialDriver: " + _serialPort.PortName + " (opened status:" + _serialPort.IsOpen +")";
+ }
}
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
index 4fa754c8e..f032623ed 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlCommunicationForm.cs
@@ -838,14 +838,27 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
/// Read configuration
- if (OptoHeadTest.ReadConfiguration(ref ihead, DiagnosticLedState.StatusUnknown))
+ if (ihead.OptoHeadTest.ReadConfiguration(DiagnosticLedState.State4))
{
error = CommErr.None;
- ihead.ConfigStruct = new ConfigStruct(); //.FromByteArray(config);
- resultStr = ihead.ConfigStruct.ToString(1);
+ //read, set and create ConfigStruct is set directly in method ReadConfiguration
+ //ihead.ConfigStruct = new ConfigStruct(); //.FromByteArray(config);
+ if (ihead.ConfigStruct != null)
+ {
+ resultStr = ihead.ConfigStruct.ToString(1);
+ }
+ else
+ {
+ resultStr = "Data not available";
+ }
+ }
+ else
+ {
+ resultStr = "Failed to read configuration";
}
- return error + Math.Max(0, Math.Min(readRetVal, 4));
+ //return error + Math.Max(0, Math.Min(readRetVal, 4));
+ return error;
}
@@ -861,6 +874,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
/// true on success
static CommErr SetTestMode(int threadId, IperlHead ihead, ref string resultStr)
{
+ log.Debug("SetTestMode threadId=" + threadId + ", ihead=" + ihead.ToString());
if (ihead.ConfigStruct == null)
{
log.Debug("ConfigStruct is null - created new in SetTestMode()");
@@ -874,7 +888,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
///
//string testModeConfigStr = multiTestParams[currentActivityStep].Activity.Substring(SetTestModeStr.Length + 1);
- if (OptoHeadTest.SetTestMode(ref ihead))
+ if (ihead.OptoHeadTest.SetTestMode())
{
log.Debug("test mode activated now");
testModeConfig = ihead.ConfigStruct.OpthoStatusMode;
@@ -899,7 +913,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
error = CommErr.Verify;
//TODO BUMI use read config
- if (OptoHeadTest.ReadConfiguration(ref ihead, DiagnosticLedState.State4))
+ if (ihead.OptoHeadTest.ReadConfiguration(DiagnosticLedState.State4))
{
if ((ihead.ConfigStruct.MeterState == ProtocolStatuses.Active) &&
(ihead.ConfigStruct.TestModeConfig == testModeConfig))
@@ -924,11 +938,12 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
/// true on success
static CommErr SetActiveMode(int threadId, IperlHead ihead, ref string resultStr)
{
+ log.Debug("SetActiveMode threadId=" + threadId);
CommErr error = CommErr.CmdActive;
/// Switch to active mode
- if (OptoHeadTest.SetActiveMode(ref ihead))
+ if (ihead.OptoHeadTest.SetActiveMode())
{
error = CommErr.None;
}
@@ -2651,7 +2666,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
switch (tag)
{
case "ReadPCB":
- txt = OptoHeadTest.ReadRequest_PCB(ref iHead);
+ txt = iHead.OptoHeadTest.ReadRequest_PCB();
break;
case "WriteRequestPort_u8_Customer_Text":
txt = "Not Supported NOW!";//OpticalHeadTest.WriteRequestPort_u8_Customer_Text(iHead);
@@ -2660,10 +2675,10 @@ namespace TBF.Rig.TestMethods.iPerlCommunication
txt = "Not Supported NOW!";//OpticalHeadTest.OpenSealing(iHead);
break;
case "StartTestMode":
- txt = OptoHeadTest.SetTestMode(ref iHead, ref success);
+ txt = iHead.OptoHeadTest.SetTestMode(ref success);
break;
case "TurnOffTestMode":
- txt = OptoHeadTest.SetActiveMode(ref iHead, ref success);
+ txt = iHead.OptoHeadTest.SetActiveMode(ref success);
break;
case "TurnOffRadio":
txt = "Not Supported NOW!";//OpticalHeadTest.TurnOffRadio(iHead);
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ConfigStruct.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ConfigStruct.cs
index 5ae3ad7b9..eb989fccb 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ConfigStruct.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/ConfigStruct.cs
@@ -17,8 +17,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
public string PCBNumberString; // dynamic
public ProtocolStatuses StatusMode; // byte
public DiagnosticLedState OpthoStatusMode;// byte
+ public string Unit; //dynamic
public string Version; // dynamic
-
public ConfigStruct()
{
@@ -80,20 +80,25 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
public override string ToString()
{
return string.Format(
- "Config: V{0} PCB#={1} StatusMode={2}",
- Version,
+ "Config: PCB#={0} StatusMode={1} Unit={2} V{3}",
+
GetPcbNrString(),
- StatusMode
+ StatusMode,
+ Unit,
+ Version
);
}
public string ToString(int sel)
{
- return string.Format("{0} PCB#={1} StatusMode={2}",
- Version,
- GetPcbNrString(),
- StatusMode
- );
+ return string.Format(
+ "Config: PCB#={0} StatusMode={1} Unit={2} V{3}",
+
+ GetPcbNrString(),
+ StatusMode,
+ Unit,
+ Version
+ );
}
public virtual void WriteBinary(BinaryWriter writer)
@@ -115,16 +120,27 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
// 2) write string bytes
writer.Write(PCBNumberStringBytes);
+ // Convert string to bytes (UTF8 is standard)
+ byte[] unitBytes = Encoding.UTF8.GetBytes(Unit);
+ // 1) write length
+ writer.Write(unitBytes.Length);
+ // 2) write string bytes
+ writer.Write(unitBytes);
+ //writer.Write(Version);
+
}
public virtual void ReadBinary(BinaryReader reader)
{
+ int ReadBytesCount = 0;
// ---- Test Data type ----
var readByte = reader.ReadByte();
if (readByte != 0x11) return; // not correct version
+ ReadBytesCount++;
// ---- Version ----
// 1) read length
int length = reader.ReadInt32();
+ ReadBytesCount += 4 + length;
// 2) read string bytes
byte[] versionBytes = reader.ReadBytes(length);
// 3) convert back to string
@@ -132,11 +148,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
// ---- PCB Number ----
// 1) read length
int lengthPCB = reader.ReadInt32();
+ ReadBytesCount += 4 + lengthPCB;
// 2) read string bytes
byte[] bytesPCB = reader.ReadBytes(lengthPCB);
// 3) convert back to string
PCBNumberString = Encoding.UTF8.GetString(bytesPCB);
-
+ // ---- Unit ----
+ // 1) read length
+ int lengthUnit = reader.ReadInt32();
+ ReadBytesCount += 4 + lengthUnit;
+ // 2) read string bytes
+ byte[] bytesUnit = reader.ReadBytes(lengthUnit);
+ // 3) convert back to string
+ Unit = Encoding.UTF8.GetString(bytesUnit);
}
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs
index 37745792e..2e23e3f6d 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/FlowDirectionDetection.cs
@@ -11,40 +11,35 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
private static readonly ILog log = LogManager.GetLogger(typeof(IperlHead));
- const int FIFO_SIZE = 64; /// 8 sec. @ 8Hz
- const double MAX_OPTO_DROPOUT = 4.5; /// sec.
-
+ const int FIFO_SIZE = 64; // 8 sec @ 8Hz
+ const double MAX_OPTO_DROPOUT = 4.5; // sec
- Int64[] volumeRawFifo; /// Volume FIFO buffer
- Int64[] timestampFifo; /// Timestamp FIFO buffer
+ private readonly double[] volumeRawFifo;
+ private readonly double[] timestampFifo; // centered timestamps
- int fifoCount; /// Number of valid FIFO items
- int fifoIx; /// Index of the next FIFO item
- DateTime lastFifoWriteTime; /// Time of the last write to FIFO
+ private int fifoCount;
+ private int fifoIx;
+ private DateTime lastFifoWriteTime;
- ///
- /// Sums for linear regression calculation
- ///
- decimal sumXX;
- decimal sumX;
- decimal sumXY;
- decimal sumY;
- decimal N;
+ // regression sums (double is ideal here)
+ private double sumXX;
+ private double sumX;
+ private double sumXY;
+ private double sumY;
- double minSlope; /// max. slope of the regressed line, always positive or 0
- double maxSlope; /// min. slope of the regressed line, always negative or 0
+ private double minSlope;
+ private double maxSlope;
+
+ // timestamp centering for numerical stability
+ private double firstTimestamp = double.NaN;
public FlowDirectionDetection()
{
- volumeRawFifo = new Int64[FIFO_SIZE];
- timestampFifo = new Int64[FIFO_SIZE];
+ volumeRawFifo = new double[FIFO_SIZE];
+ timestampFifo = new double[FIFO_SIZE];
ClearFifo();
}
-
- ///
- /// Clear FIFO data
- ///
public void ClearFifo()
{
fifoCount = 0;
@@ -55,94 +50,93 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
sumX = 0;
sumXY = 0;
sumY = 0;
- N = 0;
minSlope = 0;
maxSlope = 0;
+ firstTimestamp = double.NaN;
}
-
///
- /// Write data to FIFO
+ /// Add sample to rolling FIFO and update regression sums
///
- /// Volume
- /// Time stamp
- public void WriteToFifo(Int64 volumeRaw, Int64 timestamp)
+ public void WriteToFifo(double volumeRaw, double timestamp)
{
- ///
- /// Update sums for linear regression calculation
- ///
+ // establish time origin (CRITICAL for double precision)
+ if (double.IsNaN(firstTimestamp))
+ firstTimestamp = timestamp;
+
+ double x = timestamp - firstTimestamp; // centered time
+ double y = volumeRaw;
+
+ // remove oldest sample if buffer full
if (fifoCount == FIFO_SIZE)
{
- /// Buffer is already full, the oldest item will be re-written
- sumXX -= timestampFifo[fifoIx] * timestampFifo[fifoIx];
- sumX -= timestampFifo[fifoIx];
- sumXY -= timestampFifo[fifoIx] * volumeRawFifo[fifoIx];
- sumY -= volumeRawFifo[fifoIx];
- N--;
- }
- sumXX += timestamp * timestamp;
- sumX += timestamp;
- sumXY += timestamp * volumeRaw;
- sumY += volumeRaw;
- N++;
+ double oldX = timestampFifo[fifoIx];
+ double oldY = volumeRawFifo[fifoIx];
+
+ sumXX -= oldX * oldX;
+ sumX -= oldX;
+ sumXY -= oldX * oldY;
+ sumY -= oldY;
+ }
+ else
+ {
+ fifoCount++;
+ }
+
+ // add new sample
+ sumXX += x * x;
+ sumX += x;
+ sumXY += x * y;
+ sumY += y;
+
+ // store sample
+ timestampFifo[fifoIx] = x;
+ volumeRawFifo[fifoIx] = y;
- ///
- /// Save new values to FIFO
- ///
- volumeRawFifo[fifoIx] = volumeRaw;
- timestampFifo[fifoIx] = timestamp;
fifoIx = (fifoIx + 1) % FIFO_SIZE;
- fifoCount = Math.Min(fifoCount + 1, FIFO_SIZE);
lastFifoWriteTime = DateTime.Now;
}
-
- ///
- /// Determine whether there are enough recent FIFO data
- ///
- /// true when data valid
public bool AreFifoDataValid()
{
- return (DateTime.Now.Subtract(lastFifoWriteTime).TotalSeconds <= MAX_OPTO_DROPOUT) && (fifoCount == FIFO_SIZE);
+ return (DateTime.Now.Subtract(lastFifoWriteTime).TotalSeconds <= MAX_OPTO_DROPOUT)
+ && (fifoCount == FIFO_SIZE);
}
-
- ///
- /// Verify whether the flow direction is correct
- ///
- /// OptoHeadState.OptoAndDirOK, OptoHeadState.OptoNok or OptoHeadState.DirNok
public OptoHeadState CheckFlowDirection(Counting counting, string iPerlHeadName)
{
- if (!AreFifoDataValid()) return OptoHeadState.OptoNok;
+ if (!AreFifoDataValid())
+ return OptoHeadState.OptoNok;
try
{
- decimal numer = N * sumXY - sumX * sumY;
- decimal denom = N * sumXX - sumX * sumX;
+ double N = fifoCount;
- if (denom == 0) return OptoHeadState.DirNok;
+ double numer = N * sumXY - sumX * sumY;
+ double denom = N * sumXX - sumX * sumX;
+
+ if (Math.Abs(denom) < 1e-12)
+ return OptoHeadState.DirNok;
+
+ double slope = numer / denom;
- /// Calculate the slope of the regressed line, determine min. and max.
- double slope = (double)(numer / denom);
if (slope > maxSlope) maxSlope = slope;
if (slope < minSlope) minSlope = slope;
- if ( counting == Counting.Arbitrary ||
+ if (counting == Counting.Arbitrary ||
(counting == Counting.Positive && maxSlope > Math.Abs(2 * minSlope)) ||
(counting == Counting.Negative && minSlope < -Math.Abs(2 * maxSlope)))
{
return OptoHeadState.OptoAndDirOK;
}
- else
- {
- return OptoHeadState.DirNok;
- }
+
+ return OptoHeadState.DirNok;
}
- catch (Exception)
+ catch (Exception ex)
{
- log.ErrorFormat("{0} : CheckFlowDirection() failed", iPerlHeadName);
- return OptoHeadState.DirNok; /// ???
+ log.ErrorFormat("{0} : CheckFlowDirection() failed: {1}", iPerlHeadName, ex);
+ return OptoHeadState.DirNok;
}
}
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
index 5d2fef6ac..fd8547947 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHead.cs
@@ -13,10 +13,13 @@ using Sensus.iPerl.NfcHandler;
using NHibernate;
using System.Linq;
using System.Text;
-using System.Xml.Linq; // This line is correct and does not need to be changed.
+using System.Xml.Linq;
+using TBF.Rig.TestMethods.iPerlCommunication.communication; // This line is correct and does not need to be changed.
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.parserer;
+using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.diagnosticLed.utils;
using TBF.Rig.TestMethods.iPerlCommunication.communication.C4.hexLogger;
+using TBF.Rig.TestMethods.iPerlCommunication.communication.Utils;
using OptoTelegramFlags = TBF.Rig.TestMethods.iPerlCommunication.common.OptoTelegramFlags;
using OptoTelegramRaw = TBF.Rig.TestMethods.iPerlCommunication.common.OptoTelegramRaw;
@@ -28,6 +31,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
public class IperlHead : ComponentBase, IDevice,IRegReaderDatastream, ISessionDataMngmnt, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(IperlHead));
+ private static readonly ILog logStream = LogManager.GetLogger("StreamData");
public override string ToString() { return string.Format("{0}({1})", ClassName, Cfg.ToString(-1)); }
#if TURA_SPECIAL
@@ -41,6 +45,19 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
public const int StartEndFilterSamplesCount2 = 20; /// StartEndFilterSamplesCount = 2 * StartEndFilterSamplesCount2 + 1
public const int FeatureVectorSize = 9;
+ private OptoHeadTest _optoHeadTest;
+
+ public OptoHeadTest OptoHeadTest
+ {
+ get
+ {
+ if (_optoHeadTest == null)
+ _optoHeadTest = new OptoHeadTest(this);
+ return _optoHeadTest;
+ }
+ set { _optoHeadTest = value; }
+ }
+
readonly IperlHeadCfg iperlHeadCfg;
@@ -103,8 +120,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
///
/// Passed to OptoTelegramRaw.UpdateFromString(...)
///
- Int64 volumeRawExtLast;
- Int64 timestampExtLast;
+ double volumeRawExtLast;
+ double timestampExtLast;
FlowDirectionDetection flowDirectionDetection;
@@ -360,7 +377,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
///
/// Timestamp from the opto telegram
///
- private Int64 lastTimestamp;
+ private double lastTimestamp;
private double timestampSec;
private double timestampSec0;
@@ -383,7 +400,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
///
/// Volume of water from the opto telegram
///
- private Int64 lastVolumeRaw; /// Last read raw volume
+ private double lastVolumeRaw; /// Last read raw volume
private double volumeLtr;
private double volumeLtr0;
@@ -589,10 +606,10 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
ResultCode = 0;
- volumeLtr = 0;
- volumeLtr0 = 0;
- timestampSec = 0;
- timestampSec0 = 0;
+ volumeLtr = Double.NaN;
+ volumeLtr0 = Double.NaN;
+ timestampSec = Double.NaN;
+ timestampSec0 = Double.NaN;
extraDataPath = null;
@@ -858,6 +875,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
endWMState = volumeLtr;
wmVolume = Math.Abs(endWMState - beginWMState);
wmPulses = (int)(wmVolume * (double)PulsesPerLtr + 0.5);
+ log.Debug("wmPulses = " + wmPulses + "wmVolume = " + wmVolume + "PulsesPerLtr = " + PulsesPerLtr + "");
wmRefPulses = StateMachine.ControlBoardMain.RefPulses;
wmTestTime = timestampSec - timestampSec0;
}
@@ -980,8 +998,8 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
string line = optoSerialPort.ReadLine(); // string
byte[] bytes = optoSerialPort.Encoding.GetBytes(line);
-
- Console.WriteLine("RX ← " + HexFormatter.ToSerialHex(bytes));
+
+ log.Debug("ComPort: "+ OptoComPortNr +" OPTHO RX ← " + HexFormatter.ToSerialHex(bytes));
try
{
@@ -989,6 +1007,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
if (optoState == DataStreamState.ProcessAndSave)
{
DiagnosticLedState4Data data = (DiagnosticLedState4Data)parser.ParseLine(line, false);
+ //DiagnostigLedDataByUnit unitData = new DiagnostigLedDataByUnit(Common.Unit.m3, Common.Unit.m3, data);
int bufferIx = BufferIdx(optoDataCount);
if (synchronized)
@@ -999,11 +1018,17 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
if (data != null)
{
-
+ //TODO BUMI UNITS
+ // apply units
+ log.Debug($"OPTHO {OptoComPortNr} Parsed optho data:" + data.ToString());
+ logStream.Debug($"ID: {OptoComPortNr} " + data.ToString());
+
optoData[bufferIx].UpdateFromSmart(data, optoDataCount,
Convert.ToSingle(Sequences.ProcessData.RefFlow.Val), ref volumeRawExtLast,
ref timestampExtLast);
+ log.Debug("OPTHO UpdateFromSmart() volumeRawExtLast:" + volumeRawExtLast + " timestampExtLast:" + timestampExtLast);
+
/// CR+LF was found && (pos >= OptoTelegramRaw.Length - 2) && the telegram is OK
flowDirectionDetection.WriteToFifo(volumeRawExtLast, timestampExtLast);
OptoTelegramReceived(optoDataCount, true, volumeRawExtLast,
@@ -1056,31 +1081,31 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
}
- void OptoTelegramReceived(int currentIx, bool async, Int64 volumeRawExt, Int64 timestampRawExt)
+ void OptoTelegramReceived(int currentIx, bool async, double volumeRawExt, double timestampRawExt)
{
currentTelegramIx = currentIx;
lastVolumeRaw = volumeRawExt;
lastTimestamp = timestampRawExt;
- if (volumeLtr == 0 && volumeLtr0 == 0)
+ if (Double.IsNaN(volumeLtr) && Double.IsNaN(volumeLtr0))
{
- volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
+ volumeLtr = lastVolumeRaw;
volumeLtr0 = volumeLtr;
}
else
{
- volumeLtr = (double)lastVolumeRaw * ScalingFactor() / 16000.0;
+ volumeLtr = lastVolumeRaw;
}
- if (timestampSec == 0 && timestampSec0 == 0)
+ if (Double.IsNaN(timestampSec)&& Double.IsNaN(timestampSec0))
{
- timestampSec = (double)lastTimestamp / 8192.0;
+ timestampSec = lastTimestamp;
timestampSec0 = timestampSec;
}
else
{
- timestampSec = (double)lastTimestamp / 8192.0;
+ timestampSec = lastTimestamp;
}
}
@@ -1185,25 +1210,50 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
/// Filtered volume
double VolumeFromSamples(OptoTelegramRaw[] optoData, int optoDataCount, int unwrappedIx, double scalingFactor, int samplesCount2 = 0)
{
- if (samplesCount2 < 0) samplesCount2 = 0;
- if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
-
- Int64 sum = 0;
- for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
+ log.Debug("-- Get VolumeFromSamples() --");
+ if (unwrappedIx >= optoDataCount)
{
- int wrappedIx = BufferIdx(i);
-
- if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
- optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
- optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
- {
- return 0;
- }
-
- sum += optoData[wrappedIx].VolumeRawExt;
+ log.Debug(
+ $"-- FAILED VolumeFromSamples() - unwrappedIx {unwrappedIx} >= optoDataCount{optoDataCount}--");
+ return 0;
}
+
+ int wrappedIx = BufferIdx(unwrappedIx);
- return 0.0000625 * scalingFactor * sum / (double)(2 * samplesCount2 + 1);
+ if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
+ optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
+ optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
+ {
+ log.Debug($"-- Get VolumeFromSamples() - Quit because:{optoData[wrappedIx].Flags}--");
+ return 0;
+ }
+ log.Debug($"Valid data VolumeRawExt: {optoData[wrappedIx].VolumeRawExt}");
+ return optoData[wrappedIx].VolumeRawExt;
+
+
+
+ //
+ // if (samplesCount2 < 0) samplesCount2 = 0;
+ // if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
+ //
+ //
+ // Int64 sum = 0;
+ // for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
+ // {
+ // int wrappedIx = BufferIdx(i);
+ //
+ // if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
+ // optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
+ // optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
+ // {
+ // return 0;
+ // }
+ //
+ // sum += optoData[wrappedIx].VolumeRawExt;
+ // }
+ //
+ // return 0.0000625 * scalingFactor * sum / (double)(2 * samplesCount2 + 1);
+
}
///
@@ -1214,25 +1264,45 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
/// Filtered time
double TimeFromSamples(OptoTelegramRaw[] optoData, int optoDataCount, int unwrappedIx, int samplesCount2 = 0)
{
- if (samplesCount2 < 0) samplesCount2 = 0;
- if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
-
- Int64 sum = 0;
- for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
+ log.Debug("-- Get TimeFromSamples() --");
+ if (unwrappedIx >= optoDataCount)
{
- int wrappedIx = BufferIdx(i);
-
- if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
- optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
- optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
- {
- return 0;
- }
-
- sum += optoData[wrappedIx].TimestampExt;
+ log.Debug(
+ $"-- FAILED TimeFromSamples() - unwrappedIx {unwrappedIx} >= optoDataCount{optoDataCount}--");
+ return 0;
}
+
+ int wrappedIx = BufferIdx(unwrappedIx);
- return sum / (double)(8192 * (2 * samplesCount2 + 1));
+ if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
+ optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
+ optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
+ {
+ log.Debug($"-- Get TimeFromSamples() - Quit because:{optoData[wrappedIx].Flags}--");
+ return 0;
+ }
+ log.Debug($"Valid data TimestampExt: {optoData[wrappedIx].TimestampExt}");
+ return optoData[wrappedIx].TimestampExt;
+
+ // if (samplesCount2 < 0) samplesCount2 = 0;
+ // if ((unwrappedIx - samplesCount2) < 0 || (unwrappedIx + samplesCount2) >= optoDataCount) return 0;
+ //
+ // Int64 sum = 0;
+ // for (int i = unwrappedIx - samplesCount2; i <= unwrappedIx + samplesCount2; i++)
+ // {
+ // int wrappedIx = BufferIdx(i);
+ //
+ // if (optoData[wrappedIx].Flags != OptoTelegramFlags.OK &&
+ // optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestStart &&
+ // optoData[wrappedIx].Flags != OptoTelegramFlags.OK_TestEnd)
+ // {
+ // return 0;
+ // }
+ //
+ // sum += optoData[wrappedIx].TimestampExt;
+ // }
+ //
+ // return sum / (double)(8192 * (2 * samplesCount2 + 1));
}
///
@@ -1451,5 +1521,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
{
return this;
}
+
+
}
}
diff --git a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHeadTestCtrl.cs b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHeadTestCtrl.cs
index 4b4e30c9c..cac54258e 100644
--- a/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHeadTestCtrl.cs
+++ b/TBF/Rig/TestMethods/iPerlCommunication/iPerlHead/IperlHeadTestCtrl.cs
@@ -83,10 +83,10 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
switch (rfidCommandComboBox.SelectedValue)
{
case "ReadPCB":
- rfidListItem.Text = $"PCB: {OptoHeadTest.ReadRequest_PCB(ref iPerlHead)}";
+ rfidListItem.Text = $"PCB: {iPerlHead.OptoHeadTest.ReadRequest_PCB()}";
break;
case "SetTestMode":
- rfidListItem.Text = OptoHeadTest.SetTestMode(ref iPerlHead, ref isTestModeSuccessful);
+ rfidListItem.Text = iPerlHead.OptoHeadTest.SetTestMode(ref isTestModeSuccessful);
optoListBox.Items.Clear();
stopWorkerThread = false;
optoThread = new Thread(OptoWorker);
@@ -98,7 +98,7 @@ namespace TBF.Rig.TestMethods.iPerlCommunication.iPerlHead
break;
case "SetActiveMode":
- rfidListItem.Text = OptoHeadTest.SetActiveMode(ref iPerlHead, ref isTestModeSuccessful);
+ rfidListItem.Text = iPerlHead.OptoHeadTest.SetActiveMode(ref isTestModeSuccessful);
stopWorkerThread = true;
iPerlHead.StopDataStreamProcessing(); // close opto port
break;