iPerl test - iPerlAdjustment test method.

This commit is contained in:
Milan Hanajik
2015-08-01 21:24:32 +02:00
parent 5997a494bd
commit 52c5679c00
5 changed files with 298 additions and 26 deletions
@@ -22,7 +22,7 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
/// ///
void OpenWMErrorsForm(iPerlAdjustmentSeq myRef) void OpenWMErrorsForm(iPerlAdjustmentSeq myRef)
{ {
myRef.modelessDlg = new iPerlCommunicationForm(Program.WMsCount); myRef.modelessDlg = new iPerlCommunicationForm(WaterMeters);
modelessDlg.Show(); modelessDlg.Show();
} }
@@ -2,10 +2,14 @@
/// Copyright (c) 2013-2015 Sensus Metering Systems /// Copyright (c) 2013-2015 Sensus Metering Systems
/// ///
using System; using System;
using System.Collections.Generic;
using System.Drawing; using System.Drawing;
using System.Runtime.InteropServices;
using System.Threading;
using System.Windows.Forms; using System.Windows.Forms;
using log4net; using log4net;
using TBF.Resources; using TBF.Resources;
using TBF.BenchControl.WaterMeters.iPerl;
namespace TBF.BenchControl.TestMethods.iPerlAdjustment namespace TBF.BenchControl.TestMethods.iPerlAdjustment
{ {
@@ -13,10 +17,63 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
{ {
private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm)); private static readonly ILog log = LogManager.GetLogger(typeof(iPerlCommunicationForm));
[DllImport("libRfid.dll", EntryPoint = "getDllVersion")]
public static extern unsafe int getDllVersion();
[DllImport("libRfid.dll", EntryPoint = "openPort")]
static extern unsafe int openPort(uint comPort);
[DllImport("libRfid.dll", EntryPoint = "closePort")]
static extern unsafe int closePort();
[DllImport("libRfid.dll", EntryPoint = "readRequestPort")]
static extern unsafe int readRequestPort(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms);
[DllImport("libRfid.dll", EntryPoint = "writeRequestPort")]
static extern unsafe int writeRequestPort(MessageID messageId, int offset, int lenght, byte* ptr, int timeout_ms);
/// <summary>
/// Wrapper function with safe interface adn unsafe body
/// </summary>
/// <returns>Value returned by readRequestPort(...)</returns>
public unsafe int ReadRequestPort(MessageID messageID, int offset, int lenght, out byte[] buffer, int timeout)
{
byte[] buf = new byte[1000];
int retv;
fixed (byte* pBuf = buf)
{
retv = readRequestPort(messageID, offset, lenght, pBuf, timeout);
buffer = new byte[lenght];
for (int i = 0; i < lenght; i++) buffer[i] = buf[i];
}
return retv;
}
/// <summary>
/// Wrapper function with safe interface adn unsafe body
/// </summary>
/// <returns>Value returned by writeRequestPort(...)</returns>
public unsafe int WriteRequestPort(MessageID messageID, int offset, int lenght, byte[] buffer, int timeout)
{
int retv;
fixed (byte* pBuf = buffer)
{
retv = writeRequestPort(messageID, offset, lenght, pBuf, timeout);
}
return retv;
}
// Set to 'true' when the form closes // Set to 'true' when the form closes
public bool Completed { get { return completed; } } public bool Completed { get { return completed; } }
bool completed; bool completed;
/// <summary> Number of text boxes for serial numbers </summary> /// <summary> Number of text boxes for serial numbers </summary>
public readonly int WaterMetersCount; public readonly int WaterMetersCount;
@@ -28,6 +85,10 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
Label[] labels; Label[] labels;
TextBox[] errors; TextBox[] errors;
IList<WaterMeter> WaterMeters;
Modbus.QuidoRS.QuidoRS quido;
/// <summary> Parameterless constructor for 3 watermeters </summary> /// <summary> Parameterless constructor for 3 watermeters </summary>
@@ -90,14 +151,25 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
/// Constructor /// Constructor
/// </summary> /// </summary>
/// <param name="waterMetersCount">Number of text boxes for serial numbers</param> /// <param name="waterMetersCount">Number of text boxes for serial numbers</param>
public iPerlCommunicationForm(int waterMetersCount) public iPerlCommunicationForm(IList<GenericDevices.IWaterMeter> waterMeters)
: this() : this()
{ {
this.WaterMetersCount = waterMetersCount; this.WaterMetersCount = waterMeters.Count;
this.WaterMeters = new List<WaterMeters.iPerl.WaterMeter>();
foreach (var wm in waterMeters) this.WaterMeters.Add(wm as WaterMeters.iPerl.WaterMeter);
ShuffleTextBoxes(waterMetersCount, Program.LineSize); ShuffleTextBoxes(this.WaterMetersCount, Program.LineSize);
disabled = new bool[waterMetersCount]; disabled = new bool[this.WaterMetersCount];
foreach (var comp in StateMachine.Components)
{
if (comp is Modbus.QuidoRS.QuidoRS)
{
quido = comp as Modbus.QuidoRS.QuidoRS;
break;
}
}
} }
@@ -250,17 +322,97 @@ namespace TBF.BenchControl.TestMethods.iPerlAdjustment
private void readConfigBtn_Click(object sender, EventArgs e) private void readConfigBtn_Click(object sender, EventArgs e)
{ {
byte[] data;
int i = 0;
for (int group = 1; group <= 10; group++)
{
if (quido != null)
{
quido.SetOutputs((ushort)(16 - group));
Thread.Sleep(200);
}
foreach (var wm in WaterMeters)
{
if (wm.DebugLevel == Entities.DebugMode.Normal && wm.Group == group)
{
int r1 = openPort((uint)wm.RfidComPortNr);
int r2 = ReadRequestPort(MessageID.Configuration, 0, ConfigStruct.Length, out data, 1000);
int r3 = closePort();
if (r1==0 && r2==0 && r3==0)
{
errors[i++].Text = ConfigStruct.FromByteArray(data).ToString();
}
else
{
errors[i++].Text = "Cannot read configuration";
}
}
else
i++;
}
}
} }
private void toTestMdBtn_Click(object sender, EventArgs e) private void toTestMdBtn_Click(object sender, EventArgs e)
{ {
byte[] data = new byte[1];
data[0] = (byte)7;
int i = 0;
for (int group = 1; group <= 10; group++)
{
if (quido != null)
{
quido.SetOutputs((ushort)(16 - group));
Thread.Sleep(200);
}
foreach (var wm in WaterMeters)
{
if (wm.DebugLevel == Entities.DebugMode.Normal && wm.Group == group)
{
int r1 = openPort((uint)wm.RfidComPortNr);
int r2 = WriteRequestPort(MessageID.Command, 0, 1, data, 1000);
int r3 = closePort();
}
else
i++;
}
}
} }
private void toActiveMdBtn_Click(object sender, EventArgs e) private void toActiveMdBtn_Click(object sender, EventArgs e)
{ {
byte[] data = new byte[1];
data[0] = (byte)6;
int i = 0;
for (int group = 1; group <= 10; group++)
{
if (quido != null)
{
quido.SetOutputs((ushort)(16 - group));
Thread.Sleep(200);
}
foreach (var wm in WaterMeters)
{
if (wm.DebugLevel == Entities.DebugMode.Normal && wm.Group == group)
{
int r1 = openPort((uint)wm.RfidComPortNr);
int r2 = WriteRequestPort(MessageID.Command, 0, 1, data, 1000);
int r3 = closePort();
}
else
i++;
}
}
} }
} }
} }
@@ -0,0 +1,94 @@
///
/// Copyright (c) 2015 Sensus Metering Systems
///
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TBF.BenchControl.WaterMeters.iPerl
{
public enum MessageID
{
Calibration = 0x00, /// Access to stCalibration
Configuration = 0x01, /// Access to stConfig
Status = 0x02, /// Access to stStaus, read only
Power = 0x03, /// Access to stPower, containing power info from both processors
LCD = 0x04, /// Access to stLCD
EventData = 0x05, /// NOT USED
IntervalData = 0x06, /// NOT USED
Diagnostics = 0x07, /// Access tostMetroDiagArray, read onl
MetrologyMemory = 0x08, /// Memory block access, read only
Error_LongAck = 0x09, /// Error message
Command = 0x0A, /// Command to execute, with no arguments
Parameterizing = 0x0B, /// Parameterizing message is used in MCI-SPI interface only
Error_ShortAck = 0x0C, /// Short acknowledge message is used in MCI-SPI interface only
ChanelAlive = 0x0D, /// Channel alive message is used in MCI-SPI interface only
RadioPassthrough = 0x0E, /// RFID <-> Metrology <-> Radio passthrough message
ASICRegisterReadTest = 0x0F, /// ASIC Register read test
IMIDebugMessagesAccess = 0x10, /// IMI debug messages read test
ProductionChecksumsRead = 0x11, /// Production checksum read: Calibration (1 byte), Configuration (2 bytes), spare (4 bytes)
HardwareParametersTest = 0x12, /// Hardware Parameters Testing: User configurable fixed field drive time (1 byte)
/// <summary>
/// Notes:
/// 1. Short Ack message contains 1-byte error code and all the fields (Offset, Payload length, payload and password) will not be present.
/// 2. Channel Alive message does not contain the fields (Offset, Payload length, payload and password).
/// 3. Except the above two special messages, rest all the messages in the above table will follow the message format mentioned in sections 3.1 and 3.2.
/// </summary>
Count /// Number of MessageID-s
}
public enum MeterType : byte
{
DN15 = 0,
CoaxManifold = 1,
DN20 = 2,
DN25 = 3,
DN26 = 4, /// DN25*
DN32 = 5,
DN40 = 6,
Count /// Number of meter types
}
public enum VolumeUnits : byte
{
m3 = 0,
UK_gallon = 1,
US_gallon = 2,
Count /// Number of volume units
}
public enum FlowArrow : byte
{
No = 0,
Right = 1,
Left = 2,
Count /// Number of flow arrows
}
public enum MeterSealed : byte
{
InProduction = 0x00,
OutOfProduction = 0xA5,
Sealed = 0x5A,
}
public enum MeterState : byte
{
None = 0,
Idle = 1,
Active = 2,
Test = 3,
EndOfLife = 4,
Count /// Number of meter states
}
public enum FlowState : byte
{
No = 0,
Reverse = 1,
Forward = 2,
EmptyPipe = 3,
Count /// Number of flow states
}
}
@@ -19,9 +19,10 @@ namespace TBF.BenchControl.WaterMeters.iPerl
private static readonly ILog log = LogManager.GetLogger(typeof(WaterMeter)); private static readonly ILog log = LogManager.GetLogger(typeof(WaterMeter));
public override string ToString() { return string.Format("iPerl({0})", Cfg.ToString(1)); } public override string ToString() { return string.Format("iPerl({0})", Cfg.ToString(1)); }
readonly WaterMeterCfg iPerlCfg; readonly WaterMeterCfg iPerlCfg;
public int RfidComPortNr { get { return iPerlCfg.RfidComPortNr; } }
public int Group { get { return iPerlCfg.Group; } }
public float PulsesPerLtr { get { return iPerlCfg.ProcParams.PulsesPerLtr; } } public float PulsesPerLtr { get { return iPerlCfg.ProcParams.PulsesPerLtr; } }
@@ -71,7 +72,17 @@ namespace TBF.BenchControl.WaterMeters.iPerl
Boxes.IntBox refPulses; Boxes.IntBox refPulses;
public WaterMeter()
///
/// Opto serial port and worker thread related private variables
///
private SerialPort optoSerialPort;
private bool optoPortOpen;
private Thread workerThread;
private bool stopWorkerThread;
public WaterMeter()
{ {
} }
@@ -85,16 +96,34 @@ namespace TBF.BenchControl.WaterMeters.iPerl
public void Initialize() public void Initialize()
{ {
optoSerialPort = new SerialPort(string.Format("COM{0}", iPerlCfg.OptoComPortNr), if (DebugLevel == Entities.DebugMode.Normal)
9600, Parity.None, 8, StopBits.One); {
optoSerialPort.Handshake = Handshake.None; optoSerialPort = new SerialPort(string.Format("COM{0}", iPerlCfg.OptoComPortNr),
optoSerialPort.Open(); 9600, Parity.None, 8, StopBits.One);
optoPortOpen = true; optoSerialPort.Handshake = Handshake.None;
optoSerialPort.Open();
optoPortOpen = true;
stopWorkerThread = false; stopWorkerThread = false;
workerThread = new Thread(Worker); workerThread = new Thread(Worker);
workerThread.Start(); workerThread.Start();
return; }
}
public void RunDeviceBefore()
{
}
public void RunDeviceAfter()
{
}
public void StopDevice()
{
stopWorkerThread = true;
workerThread.Join(2000);
optoSerialPort.Close();
optoPortOpen = false;
} }
/// <summary> /// <summary>
@@ -162,15 +191,6 @@ namespace TBF.BenchControl.WaterMeters.iPerl
} }
///
/// Measurement serial port and worker thread related private variables
///
private SerialPort optoSerialPort;
private bool optoPortOpen;
private Thread workerThread;
private bool stopWorkerThread;
void Worker() void Worker()
{ {
while (!stopWorkerThread) while (!stopWorkerThread)
@@ -187,7 +207,7 @@ namespace TBF.BenchControl.WaterMeters.iPerl
} }
else else
{ {
OnOptoReceived(this, new OptoReceivedEventArgs(".")); //OnOptoReceived(this, new OptoReceivedEventArgs("."));
} }
} }
} }
+6
View File
@@ -42,6 +42,7 @@
<DefineConstants>TRACE;DEBUG;MUNICH</DefineConstants> <DefineConstants>TRACE;DEBUG;MUNICH</DefineConstants>
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType> <DebugType>pdbonly</DebugType>
@@ -51,6 +52,7 @@
<ErrorReport>prompt</ErrorReport> <ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel> <WarningLevel>4</WarningLevel>
<PlatformTarget>AnyCPU</PlatformTarget> <PlatformTarget>AnyCPU</PlatformTarget>
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
</PropertyGroup> </PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'"> <PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
<DebugSymbols>true</DebugSymbols> <DebugSymbols>true</DebugSymbols>
@@ -302,8 +304,12 @@
<Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlCommunicationForm.designer.cs"> <Compile Include="BenchControl\TestMethods\iPerlAdjustment\iPerlCommunicationForm.designer.cs">
<DependentUpon>iPerlCommunicationForm.cs</DependentUpon> <DependentUpon>iPerlCommunicationForm.cs</DependentUpon>
</Compile> </Compile>
<Compile Include="BenchControl\WaterMeters\iPerl\CalibrationStruct.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\ConfigStruct.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\Enums.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\OptoReceivedEventArgs.cs" /> <Compile Include="BenchControl\WaterMeters\iPerl\OptoReceivedEventArgs.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\ProcParams.cs" /> <Compile Include="BenchControl\WaterMeters\iPerl\ProcParams.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\StatusStruct.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\WaterMeter.cs" /> <Compile Include="BenchControl\WaterMeters\iPerl\WaterMeter.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\WaterMeterCfg.cs" /> <Compile Include="BenchControl\WaterMeters\iPerl\WaterMeterCfg.cs" />
<Compile Include="BenchControl\WaterMeters\iPerl\WaterMeterCfgCtrl.cs"> <Compile Include="BenchControl\WaterMeters\iPerl\WaterMeterCfgCtrl.cs">