More iPerl communication

This commit is contained in:
Milan Hanajik 2015-08-14 14:33:36 +02:00
parent bf376b4ff0
commit 4166bf8d87
3 changed files with 205 additions and 56 deletions

View File

@ -75,6 +75,14 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
const int CommTimeout = 500;
const int MaxCommRetries = 3;
const string ReadConfigurationStr = "Read configuration";
const string SetTestModeStr = "Set Test mode"; /// Example: "Set Test mode 0xA0"
const string SetActiveModeStr = "Set Active mode";
const string ReadCalibrationStr = "Read calibration";
const string WriteCalibrationFactorStr = "Write calibration factor";
const string ResetQ2CorrectionStr = "Reset Q2 correction";
const string WriteQ2CorrectionStr = "Write Q2 correction";
// Set to 'true' when the form closes
public bool Completed { get { return formCompleted; } }
@ -393,10 +401,13 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
wmFound = true;
if (wm.DebugLevel == Entities.DebugMode.Normal)
{
if (activity.ToLower().Equals("read configuration")) ReadConfig(wm, threadId, wmNr);
else if (activity.ToLower().Equals("read calibration")) ReadCalibration(wm, threadId, wmNr);
else if (activity.ToLower().Contains("set test mode")) SetToTestMode(wm, threadId, wmNr);
else if (activity.ToLower().Equals("set active mode")) SetToActiveMode(wm, threadId, wmNr);
if (activity.ToLower().Equals(ReadConfigurationStr.ToLower())) ReadConfiguration(wm, threadId, wmNr);
else if (activity.ToLower().Contains(SetTestModeStr.ToLower())) SetTestMode(wm, threadId, wmNr);
else if (activity.ToLower().Equals(SetActiveModeStr.ToLower())) SetActiveMode(wm, threadId, wmNr);
else if (activity.ToLower().Equals(ReadCalibrationStr.ToLower())) ReadCalibration(wm, threadId, wmNr);
else if (activity.ToLower().Equals(WriteCalibrationFactorStr.ToLower())) WriteCalibrationFactor(wm, threadId, wmNr);
else if (activity.ToLower().Equals(ResetQ2CorrectionStr.ToLower())) ResetQ2Correction(wm, threadId, wmNr);
else if (activity.ToLower().Equals(WriteQ2CorrectionStr.ToLower())) WriteQ2Correction(wm, threadId, wmNr);
else OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Invalid activity"));
}
else
@ -419,7 +430,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void ReadConfig(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
static void ReadConfiguration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] config = null;
@ -445,7 +456,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if (success)
{
wm.ConfigStruct = ConfigStruct.FromByteArray(config);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(config).ToString(1)));
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1)));
}
else if (wm.Disabled)
{
@ -457,50 +468,6 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
}
}
/// <summary>
/// Read a complete calibration structure of the watermeter
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void ReadCalibration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] calib = null;
if (!wm.Disabled)
{
success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port
if (success)
{
success = false;
/// Read calibration
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, CalibrationStruct.Length, out calib, CommTimeout)) { success = true; break; }
}
}
closePort(); /// Close RFID port
}
if (success)
{
wm.CalibrationStruct = CalibrationStruct.FromByteArray(calib);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Calibration successfully read"));
}
else if (wm.Disabled)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read calibration"));
}
}
/// <summary>
/// Set the watermeter to the test mode.
/// If testModeConfig is specified as a hexadeximal number appended to "set test mode ", it is verified
@ -510,13 +477,16 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void SetToTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
static void SetTestMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] cfg_0_3 = null;
if (!wm.Disabled)
{
string testModeConfigStr; /// TODO
Byte testModeConfig; /// TODO
success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
if (success)
@ -560,8 +530,14 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
}
}
static void SetToActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
/// <summary>
/// Set the watermeter to the active mode.
/// Read a part of configuration afterwards to verify the mode was set correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void SetActiveMode(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] cfg_0_3 = null;
@ -589,7 +565,7 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
/// Read configuration
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out cfg_0_3, CommTimeout)) { success = true; break; }
if (0 == ReadRequestPort(MessageID.Configuration, 0, 4, out cfg_0_3, CommTimeout)) { success = true; break; }
}
}
@ -598,7 +574,8 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
if (success)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, ConfigStruct.FromByteArray(cfg_0_3).ToString(1)));
wm.ConfigStruct.Update(cfg_0_3, 0);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.ConfigStruct.ToString(1)));
}
else if (wm.Disabled)
{
@ -610,6 +587,123 @@ namespace TBF.BenchControl.TestMethods.iPerlCommunication
}
}
/// <summary>
/// Read a complete calibration structure from the watermeter
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void ReadCalibration(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] calib = null;
//if (activity.Length >
//string testModeConfigStr = activity.Substring(activity.IndexOf()
if (!wm.Disabled)
{
success = (0 == openPort(wm.RfidComPortNr)); /// Open RFID port
if (success)
{
success = false;
/// Read calibration
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Configuration, 0, CalibrationStruct.Length, out calib, CommTimeout)) { success = true; break; }
}
}
closePort(); /// Close RFID port
}
if (success)
{
wm.CalibrationStruct = CalibrationStruct.FromByteArray(calib);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.CalibrationStruct.ToString()));
}
else if (wm.Disabled)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot read calibration"));
}
}
/// <summary>
/// Write the calculated calibration factor to the water meter.
/// Read a part of CalibrationStruct afterwards to verify factor was written correctly.
/// </summary>
/// <param name="wm">Water meter object</param>
/// <param name="threadId">Thread ID</param>
/// <param name="wmNr">Water meter number 1 .. 40</param>
static void WriteCalibrationFactor(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
bool success = false;
byte[] calib_2_3 = null;
if (!wm.Disabled)
{
success = (openPort(wm.RfidComPortNr) == 0); /// Open RFID port
if (success)
{
success = false;
ushort factor = wm.CalibrationFactor;
/// Switch to active mode
UInt16 newCalFactor = wm.CalculatedCalibrationFactor;
byte[] data = new byte[2] { (byte)(newCalFactor & 0x00FF), (byte)((newCalFactor >> 8) & 0x00FF) };
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == WriteRequestPort(MessageID.Calibration, 2, 2, data, CommTimeout)) { success = true; break; }
}
}
if (success)
{
success = false;
/// Read configuration
for (int j = 0; j < MaxCommRetries; j++)
{
if (0 == ReadRequestPort(MessageID.Calibration, 2, 2, out calib_2_3, CommTimeout)) { success = true; break; }
}
}
closePort(); /// Close RFID port
}
if (success)
{
wm.CalibrationStruct.Update(calib_2_3, 2);
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, wm.CalibrationStruct.ToString()));
}
else if (wm.Disabled)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Watermeter is disabled"));
}
else
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "Cannot switch to active mode"));
}
}
static void ResetQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "ResetQ2Correction simulated"));
}
static void WriteQ2Correction(WaterMeters.iPerl.WaterMeter wm, int threadId, int wmNr)
{
OnCommCompleted(null, new CommCompletedEventArgs(threadId, wmNr, "WriteQ2Correction simulated"));
}
/// <summary>
/// Called when communication with one watermeter is completed

View File

@ -89,7 +89,12 @@ namespace TBF.BenchControl.WaterMeters.iPerl
return result;
}
public static CalibrationStruct FromByteArray(byte[] data)
/// <summary>
/// Create a calibration structure from a complete byte array
/// </summary>
/// <param name="data">A complete byte array data</param>
/// <returns>CalibrationStruct or null when byte array was not complete</returns>
public static CalibrationStruct FromByteArray(byte[] data)
{
if (data.Length != Length) return null;
@ -117,6 +122,46 @@ namespace TBF.BenchControl.WaterMeters.iPerl
return result;
}
/// <summary>
/// Update the calibration structure from an incomplete byte array
/// </summary>
/// <param name="data">Byte array data</param>
/// <param name="offset">Offset of byte array data in CalibrationStruct</param>
/// <returns>true when successful, false when data are not appropriate</returns>
public bool Update(byte[] data, int offset)
{
if (offset == 2 && data.Length == 2)
{
/// Data containing iPerl calibration factor
Calibration = (UInt16)(data[2 - offset] + 256 * data[3 - offset]);
return true;
}
else if (offset == 0 && data.Length == Length)
{
/// Data containing a complete CalibrationStruct
Version = data[0];
MeterType = (MeterType)data[1];
Calibration = (UInt16)(data[2] + 256 * data[3]);
VolumeUnits = (VolumeUnits)data[4];
FlowArrow = (FlowArrow)data[5];
FWVersion = (UInt16)(data[6] + 256 * data[7]);
TargetField[0] = (UInt16)(data[8] + 256 * data[9]);
TargetField[1] = (UInt16)(data[10] + 256 * data[11]);
TargetField[2] = (UInt16)(data[12] + 256 * data[13]);
RecipMeanCurrent = (UInt16)(data[14] + 256 * data[15]);
ThresholdVolume = (UInt16)(data[16] + 256 * data[17]);
ThresholdTime = (UInt16)(data[18] + 256 * data[19]);
FlowActivationThr = (UInt16)(data[20] + 256 * data[21]);
VolumeArrowThr = (UInt16)(data[22] + 256 * data[23]);
CalibrationTime = (((UInt32)data[27] * 256 + data[26]) * 256 + data[25]) * 256 + data[24];
SerialNumber = ((((UInt64)data[32] * 256 + data[31]) * 256 + data[30]) * 256 + data[29]) * 256 + data[28];
MeterSealed = (MeterSealed)data[33];
CheckSum = data[34];
return true;
}
else
return false;
}
public override string ToString()
{

View File

@ -78,6 +78,16 @@ namespace TBF.BenchControl.WaterMeters.iPerl
/// </summary>
public CalibrationStruct CalibrationStruct;
public ushort CalibrationFactor { get { return CalibrationStruct.Calibration; } }
public ushort CalculatedCalibrationFactor
{
get
{
return (UInt16)((double)CalibrationStruct.Calibration * 1.1); /// TODO: real calculation
}
}
Boxes.IntBox pulses;
Boxes.IntBox refPulses;