tbf/TestBenchFramework/BenchControl/Elde/ControlComWrap.cs
2014-07-28 10:15:38 +02:00

269 lines
14 KiB
C#

using System;
using log4net;
namespace TBF.BenchControl.Elde
{
public class ControlComWrap : IControlCom
{
private static readonly ILog log = LogManager.GetLogger(typeof(ControlComWrap));
///
/// Properties
///
public StatusP StatusP { get { return (StatusP)ctrlBrdComponent.StatusP; } }
public float ReferenceFreq { get { return 1000.0f * ctrlBrdComponent.referenceFreq; } } /// In [Hz] 0..2500, nom.=2000
public int EtPulses(int wmNr0)
{
return (int)ctrlBrdComponent.etPulses[wmNr0];
}
public int WMeterPulses(int wmNr0)
{
return (int)ctrlBrdComponent.wMeterPuls[wmNr0];
}
public int WMeterReference(int wmNr0) { return (int)ctrlBrdComponent.wMeterReference[wmNr0]; }
public uint RegulValveDAC { get { return ctrlBrdComponent.StavDA; } }
public float Pressure(int prsNr0) { return ctrlBrdComponent.pressure[prsNr0]; }
public float Temperature(int tmpNr0) { return ctrlBrdComponent.temperature[tmpNr0]; }
public RegulValveState RegulValveState(int rvNr1) { return (RegulValveState)ctrlBrdComponent.rValveStatus[rvNr1 - 1]; }
public ulong RRoute { get { return ctrlBrdComponent.rRoute; } }
public uint DivTime { get { return ctrlBrdComponent.divTime; } }
public float TTime { get { return ctrlBrdComponent.Ttime; } }
public uint FmState { get { return ctrlBrdComponent.fMState; } }
public uint BeginState(int wmNr0) { return ctrlBrdComponent.beginSt[wmNr0]; }
public float ReferenceFlow { get { return ctrlBrdComponent.referenceFlow; } }
public float RValvePosition(int rvNr1)
{
//return ctrlBrdComponent.RValvePosition[rvNr1 - 1];
return ctrlBrdComponent.Analogy[rvNr1 - 1]; /// Fixes bug: RValvePosition returns 0 all the time
}
public float DivSamples(int ms) { return ctrlBrdComponent.DIVSamples[ms, 0]; }
public int ScopeSamples(int i, int j, int k) { return ctrlBrdComponent.ScopeSamples[i, j, k]; }
public uint DigitalInputs { get { return ctrlBrdComponent.Vstupy; } }
public float AnalogInput(int adcNr0) { return ctrlBrdComponent.Analogy[adcNr0]; }
public uint AnalogInputRaw(int adcNr0, int bank) { return ctrlBrdComponent.AnalogyRaw[adcNr0, bank]; } /// bank0=RV, bank1=Temp
public float ReferenceVolume { get { return ctrlBrdComponent.ReferenceVolume; } }
public float VyslExt(int wmNr0, int what) { return ctrlBrdComponent.VyslExt[wmNr0, what]; }
public void SetWeight(int pos, float mass) { ctrlBrdComponent.Weight[pos] = mass; }
///
/// Reference to the control board component
///
#if DN100
private ControlCom2VB.ControlCom2panel ctrlBrdComponent;
#elif MUNICH
private ControlComponent3Munich.UserControl1 ctrlBrdComponent;
#elif FUZHOU150
private ControlComponent3Munich.UserControl1 ctrlBrdComponent;
#endif
/// <summary>
/// Constructor that initializes the control board component reference
/// </summary>
/// <param name="ctrlBrdComponent"></param>
#if DN100
public ControlComWrap(ControlCom2VB.ControlCom2panel ctrlBrdComponent)
#elif MUNICH
public ControlComWrap(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
#elif FUZHOU150
public ControlComWrap(ControlComponent3Munich.UserControl1 ctrlBrdComponent)
#endif
{
this.ctrlBrdComponent = ctrlBrdComponent;
}
/// <summary>
/// Sends calibration and configuration data to the control board.
/// </summary>
/// <param name="rvCalib">Regulating valves calib.coefs, ix1 = valve nr. (1..5), ix2 = coef.nr. (0..1), values typ. c0 = 0, c1 = 0.2</param>
/// <param name="meretA">Meret address, index = 0..1, value typ. 99 and 100</param>
/// <param name="usedCom">COM port number of the control board (typ. 1)</param>
/// <param name="tempCalib">Temp.calc.coefs, ix1 = temp.sens.nr. (0..7 ???), ix2 = coef.nr</param>
/// <param name="etCalib">Etalon nominal values</param>
/// <param name="divEdge">Percentages for switching of diverters, ix = diverter nr.(0,1), typ.value 50 (%)</param>
/// <param name="balanceRange">Balance range = volume of the tanks on the balaces (ix=0,1)</param>
public void SendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
if (Program.MainWnd.InvokeRequired)
{
/// When SendCalibData(...) called from the worker thread
object[] args = new object[] { rvCalib, meretA, usedCom, tempCalib, etCalib, divEdge, balanceRange };
Program.MainWnd.Invoke((SendCalibDataDlgt)DoSendCalibData, args); /// Invoke required as component was created in UI thread
}
else
{
/// When SendCalibData(...) called from the UI thread
DoSendCalibData(rvCalib, meretA, usedCom, tempCalib, etCalib, divEdge, balanceRange);
}
}
///
delegate void SendCalibDataDlgt(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange);
///
private void DoSendCalibData(uint[,] rvCalib, byte[] meretA, int usedCom, float[,] tempCalib,
float[] etCalib, uint[] divEdge, uint[] balanceRange)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} SendCalibData(COM{1}) rvCalib[0,0]={2} rvCalib[0,1]={3} rvCalib[1,0]={4} rvCalib[1,1]={5}\r\n",
// DateTime.Now.ToLongTimeString(), usedCom,
// rvCalib[0,0], rvCalib[0,1], rvCalib[1,0], rvCalib[1,1]));
log.InfoFormat("SendCalibData(COM{0}) rvCalib[0,0]={1} rvCalib[0,1]={2} rvCalib[1,0]={3} rvCalib[1,1]={4}\r\n",
usedCom, rvCalib[0,0], rvCalib[0,1], rvCalib[1,0], rvCalib[1,1]);
#if (DN100)
ctrlBrdComponent.ExternalCom = true;
#endif
ctrlBrdComponent.SendCalibData(rvCalib, meretA, (byte)usedCom, tempCalib, etCalib, divEdge, balanceRange);
}
/// <summary>
/// Control of regulating valves.
/// </summary>
/// <param name="valveNo">Regulating valve nr. (1..5)</param>
/// <param name="valveMode">Valve regulation mode, see the enum</param>
/// <param name="valveValue">Target position or target frequency or pulse duration</param>
public void ValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue)
{
if (Program.MainWnd.InvokeRequired)
{
/// When ValveMove(...) called from the worker thread
object[] args = new object[] { valveNo, valveMode, valveValue };
Program.MainWnd.Invoke((ValveMoveDlgt)DoValveMove, args); /// When ValveMove called from a worker thread
}
else
{
/// When ValveMove(...) called from the UI thread
DoValveMove(valveNo, valveMode, valveValue); /// When ValveMove called from the UI thread
}
}
///
delegate void ValveMoveDlgt(int valveNo, RegulValveMode valveMode, float[] valveValue);
///
private void DoValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} ValveMove({1}, {2}, [{3}, {4}])\r\n",
// DateTime.Now.ToLongTimeString(),
// valveNo,
// valveMode,
// valveValue[0],
// valveValue[1]));
log.InfoFormat("ValveMove({0}, {1}, [{2}, {3}])\r\n", valveNo, valveMode, valveValue[0], valveValue[1]);
ctrlBrdComponent.ValveMove((byte)valveNo, (byte)valveMode, valveValue);
}
/// <summary>
/// Sends a command to the control board.
/// </summary>
/// <param name="cmd">See ControlBoard.Command enum</param>
/// <param name="refFlowMeterNr">Reference flow meter number (1..5)</param>
/// <param name="route">Route: 64-bit installation specific number</param>
/// <param name="refPulses">Test duration as a number of reference flow meter pulses</param>
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
/// <param name="filterConstant">0 = No filtering (0..255)</param>
/// <param name="FMFreq">Freq.inverter control (not applicable in DT100, Munich)</param>
/// <param name="regConst">Coefficient used to control the regulation valve (1..100)</param>
/// <param name="shortImp">0 = default value, 1 = spec. processing of very short pulses</param>
/// <param name="stopDevs">What to stop</param>
public void SendCommand(Command cmd, int refFlowMeterNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs)
{
if (Program.MainWnd.InvokeRequired)
{
/// When SendCommand(...) called from the worker thread
object[] args = new object[] { cmd, refFlowMeterNr, route, totalRefPulses, testMethods,
filterConstant, fmFreq, regConst, shortImp, stopDevs };
Program.MainWnd.Invoke((SendCommandDlgt)DoSendCommand, args); /// Component was created in UI thread - use Invoke()
}
else
{
/// When SendCommand(...) called from the UI thread
DoSendCommand(cmd, refFlowMeterNr, route, totalRefPulses, testMethods,
filterConstant, fmFreq, regConst, shortImp, stopDevs);
}
}
///
delegate void SendCommandDlgt(Command cmd, int refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs);
///
private void DoSendCommand(Command cmd, int refFlowMeterNr, ulong route, int totalRefPulses, TestMethods testMethods,
float filterConstant, float[] fmFreq, int regConst, int shortImp, StopDevs stopDevs)
{
//TBF.UiBridge.Bridge.OnLog(this, string.Format("{0} SendCommand({1}, {2}, {3}, {4}, {5}, {6}, [{7},{8}], {9}, {10}, {11})\r\n",
// DateTime.Now.ToLongTimeString(),
// cmd,
// refFlowMeterNr,
// route.ToString("X"),
// totalRefPulses,
// testMethods,
// filterConstant,
// fmFreq[0],
// fmFreq[1],
// regConst,
// shortImp,
// stopDevs));
log.InfoFormat("SendCommand({0}, {1}, {2}, {3}, {4}, {5}, [{6},{7}], {8}, {9}, {10})\r\n",
cmd,
refFlowMeterNr,
route.ToString("X"),
totalRefPulses,
testMethods,
filterConstant,
fmFreq[0],
fmFreq[1],
regConst,
shortImp,
stopDevs);
#if DN100
ctrlBrdComponent.SendCommand((uint)cmd, (byte)refFlowMeterNr, (ulong)route, (uint)totalRefPulses, (uint)testMethods,
filterConstant, fmFreq[0], (uint)regConst, (uint)shortImp, (uint)stopDevs);
#elif MUNICH
ctrlBrdComponent.SendCommand((uint)cmd, (byte)refFlowMeterNr, (ulong)route, (uint)totalRefPulses, (uint)testMethods,
filterConstant, fmFreq[0], (uint)regConst, (uint)shortImp, (uint)stopDevs);
#else
ctrlBrdComponent.SendCommand((uint)cmd, (byte)refFlowMeterNr, (ulong)route, (uint)totalRefPulses, (uint)testMethods,
filterConstant, fmFreq, (uint)regConst, (uint)shortImp, (uint)stopDevs);
#endif
}
enum CommType
{
Rx, /// Receive data only
TxRx, /// Transmit and receive data
}
public void RunDeviceBefore()
{
object[] args = new object[] { CommType.Rx };
MakeCommDlgt dlgt = MakeComm;
Program.MainWnd.Invoke(dlgt, args); /// Invoke MakeExtComm(.) in the UI thread
}
public void RunDeviceAfter()
{
object[] args = new object[] { CommType.TxRx };
MakeCommDlgt dlgt = MakeComm;
Program.MainWnd.Invoke(dlgt, args); /// Invoke MakeExtComm(.) in the UI thread
}
/// <summary>
/// A delegate to execute the SendCommand() in the UI thread
/// </summary>
delegate void MakeCommDlgt(CommType extComm);
/// <summary>
/// Executes the SendCommand(...) and MakeExtCom() in the UI thread
/// </summary>
void MakeComm(CommType commType)
{
if (ctrlBrdComponent.ExternalCom)
{
ctrlBrdComponent.MakeExtCom((commType == CommType.Rx) ? false : true);
}
}
}
}