(1) IDatastreamReader iface in IperlHead and SerialStream, (2) SerialStream buffer size, (3) TimeFieldFormat==FieldFormat.None implemented, ver. 2.18.911

This commit is contained in:
Milan Hanajik
2018-06-04 08:15:27 +02:00
parent 385825c9e8
commit 392a02b83c
12 changed files with 220 additions and 166 deletions
@@ -23,7 +23,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public float RefFlow; /// [m3/h]
public int Counter;
const int MaxDataLength = 256;
const int MaxDataLength = 512;
char[] data = new char[MaxDataLength];
int dataLength;
@@ -106,56 +106,72 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
/// Copy data into the fixed size buffer
dataLength = frame.Length - 2;
for (int i = 0; i < Math.Min(MaxDataLength, dataLength); i++) data[i] = frame[i];
bool f1 = true;
bool f2 = true;
bool f3 = true;
bool f1 = UInt32.TryParse(frame.Substring(ff.VolumeFieldStart, ff.VolumeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
bool f2 = UInt32.TryParse(frame.Substring(ff.TimeFieldStart, ff.TimeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
bool f3 = byte.TryParse(frame.Substring(ff.FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
if (ff.VolumeFieldFormat == FieldFormat.HexadecimalWindow)
{
f1 = UInt32.TryParse(frame.Substring(ff.VolumeFieldStart, ff.VolumeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out VolumeRaw);
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & ff.VolumeWindowMask) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected + ff.VolumeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected - ff.VolumeWrapIncrement;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
}
if (ff.TimeFieldFormat == FieldFormat.HexadecimalWindow)
{
f2 = UInt32.TryParse(frame.Substring(ff.TimeFieldStart, ff.TimeFieldLength), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out Timestamp);
///
/// Cope with 'Timestamp' overflow
///
Int64 uncorrected = (Int64)(((UInt64)timestampExtLast & ff.TimeWindowMask) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected + ff.TimeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected - ff.TimeWrapIncrement;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
}
else if (ff.TimeFieldFormat == FieldFormat.None)
{
TimestampExt = ff.RawTimeIncrementPerFrame * counter;
}
f3 = byte.TryParse(frame.Substring(ff.FrameLength - 4, 2), NumberStyles.HexNumber, CultureInfo.CurrentCulture, out CheckSum);
bool allOk = f1 && f2 && f3;
Flags = allOk ? FrameFlags.OK : FrameFlags.InvalidFrame;
///
/// Cope with 'VolumeRaw' overflow
///
Int64 uncorrected = (Int64)(((UInt64)volumeRawExtLast & ff.VolumeWindowMask) | VolumeRaw);
if (Math.Abs(uncorrected - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected + ff.VolumeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.VolumeWrapIncrement - volumeRawExtLast) <= ff.VolumeWrapThreshold)
{
VolumeRawExt = volumeRawExtLast = uncorrected - ff.VolumeWrapIncrement;
}
else
{
VolumeRawExt = volumeRawExtLast = uncorrected;
}
///
/// Cope with 'Timestamp' overflow
///
uncorrected = (Int64)(((UInt64)timestampExtLast & ff.TimeWindowMask) | Timestamp);
if (Math.Abs(uncorrected - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected;
}
else if (Math.Abs(uncorrected + ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected + ff.TimeWrapIncrement;
}
else if (Math.Abs(uncorrected - ff.TimeWrapIncrement - timestampExtLast) <= ff.TimeWrapThreshold)
{
TimestampExt = timestampExtLast = uncorrected - ff.TimeWrapIncrement;
}
else
{
TimestampExt = timestampExtLast = uncorrected;
}
return allOk;
}
@@ -8,15 +8,16 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public class FrameFormat
{
public int FrameLength; /// Frame length in characters/bytes, 0 = unknown
public double FrameFrequency; /// Number of frames per second (Hz)
public readonly Config.Unit VolumeUnits;
public readonly double VolumeScaleFactor; /// Volume =
public readonly double VolumeScaleFactor; /// Volume in VolumeInits = volmeRaw / VolumeScaleFactor
public readonly int VolumeFieldStart; /// Start of the volume field: 0-based index of the first character, -1 = no volume field in the frame
public readonly int VolumeFieldEnd; /// End of the volume field: 0-based index of the last character
public readonly FieldFormat VolumeFieldFormat; /// Hexadecimal or Decimal
public readonly Config.Unit TimeUnits;
public readonly double TimeScaleFactor; /// Time =
public readonly double TimeScaleFactor; /// Time in TimeUnits = timeRaw / TimeScaleFactor
public readonly int TimeFieldStart; /// Start of the time field: 0-based index of the first character, -1 = no time field in the frame
public readonly int TimeFieldEnd; /// End of the time field: 0-based index of the last character
public readonly FieldFormat TimeFieldFormat; /// Hexadecimal or Decimal
@@ -34,13 +35,16 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
public readonly Int64 TimeWrapIncrement;
public readonly Int64 TimeWrapThreshold;
public FrameFormat(int frameLength,
public readonly long RawTimeIncrementPerFrame;
public FrameFormat(int frameLength, double frameFrequency,
Config.Unit volumeUnits, double volumeScaleFactor,
int volumeFieldStart, int volumeFieldEnd, FieldFormat volumeFieldFormat,
Config.Unit timeUnits, double timeScaleFactor,
int timeFieldStart, int timeFieldEnd, FieldFormat timeFieldFormat)
{
FrameLength = frameLength;
FrameFrequency = frameFrequency;
VolumeUnits = volumeUnits;
VolumeScaleFactor = volumeScaleFactor;
@@ -54,6 +58,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
TimeFieldEnd = timeFieldEnd;
TimeFieldFormat = timeFieldFormat;
RawTimeIncrementPerFrame = (FrameFrequency != 0) ? (long)Math.Round(TimeScaleFactor / FrameFrequency) : 1L;
VolumeFieldLength = VolumeFieldEnd - VolumeFieldStart + 1;
@@ -13,7 +13,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
/// <summary>
/// This component = instance of this class is a placeholder for a combined main watermeter
/// </summary>
public class SerialStream : ComponentBase, IDevice, GenericDevices.IRegisterReader, GenericDevices.IHasTestName, IOperation
public class SerialStream : ComponentBase, IDevice, GenericDevices.IDatastreamReader, GenericDevices.IHasTestName, IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SerialStream));
public override string ToString() { return string.Format("RegisterReaders.SerialStream({0})", Cfg.ToString(1)); }
@@ -100,9 +100,10 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
private double volumeLtr; ///
private double volumeLtr0;
public double VolumeLtrStart; /// Test start volume for metrology
public double VolumeLtrEnd; /// Test end volume for metrology
public double VolumeLtrRef; /// Reference volume or metrology
public double VolumeLtrStart { get { return volumeLtrStart; } } /// Test start volume for metrology
public double VolumeLtrEnd { get { return volumeLtrEnd; } } /// Test end volume for metrology
double volumeLtrStart; /// Test start volume for metrology
double volumeLtrEnd; /// Test end volume for metrology
double volumeLtrEnd1; /// auxiliary buffer1 to keep the end volume before test stops
double volumeLtrEnd2; /// auxiliary buffer2 to keep the end volume before test stops
double volumeLtrEnd3; /// auxiliary buffer3 to keep the end volume before test stops
@@ -130,7 +131,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
DatastreamFrame[] datastreamFrames;
const int MaxDatastreamFramesCount = 40000;
const int MaxDatastreamFramesCount = 80000; /// almost 3h at 8 Hz
int datastreamFramesCount;
string datastreamLogFileName;
@@ -194,7 +195,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
if (DebugLevel == DebugMode.Normal)
{
datastreamParsingEnabled = false;
currentFrameFormat = new FrameFormat(FrameLength,
currentFrameFormat = new FrameFormat(FrameLength, FrameFrequency,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
@@ -322,7 +323,7 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
testName,
repetitionNr);
StartParsingDatastream(new FrameFormat(FrameLength,
StartParsingDatastream(new FrameFormat(FrameLength, FrameFrequency,
VolumeUnits, VolumeScaleFactor,
VolumeFieldStart, VolumeFieldEnd, VolumeFieldFormat,
TimeUnits, TimeScaleFactor,
@@ -338,13 +339,13 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
if (sampleNr == 4)
{
/// Take the test start sample
VolumeLtrStart = volumeLtr;
volumeLtrStart = volumeLtr;
timestampSecStart = timestampSec;
TestStartFrameIx = frameIx;
}
/// Shift data in pipelines
VolumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd = volumeLtrEnd3;
volumeLtrEnd3 = volumeLtrEnd2;
volumeLtrEnd2 = volumeLtrEnd1;
volumeLtrEnd1 = volumeLtr;
@@ -493,7 +494,8 @@ namespace TBF.BenchControl.RegisterReaders.SerialStream
synchronized = true;
}
// CR+LF found and (pos >= OptoTelegramRaw.Length - 2)
else if (datastreamFrames[datastreamFramesCount].UpdateFromString(allRcvd.Substring(pos - ff.FrameLength + 2, ff.FrameLength), ff, datastreamFramesCount, ref volumeRawExtLast, ref timestampExtLast))
else if (datastreamFrames[datastreamFramesCount].UpdateFromString(allRcvd.Substring(pos - ff.FrameLength + 2, ff.FrameLength),
ff, datastreamFramesCount, ref volumeRawExtLast, ref timestampExtLast))
{
OptoTelegramRreceived(datastreamFramesCount++, synchronized2);
synchronized2 = synchronized;