393 lines
15 KiB
C#
393 lines
15 KiB
C#
using System;
|
|
using System.Text;
|
|
using System.IO.Ports;
|
|
using System.Collections.Generic;
|
|
using TBF.BenchControl.Generic;
|
|
using TBF.BenchControl.GenericDevices;
|
|
using log4net;
|
|
|
|
namespace TBF.BenchControl.Elde
|
|
{
|
|
public class ControlBoardDev : IComponent, IDevice, IValveControl
|
|
{
|
|
/// <summary>
|
|
/// Info:
|
|
/// Warn:
|
|
/// Error:
|
|
/// </summary>
|
|
private static readonly ILog log = LogManager.GetLogger(typeof(ControlBoardDev));
|
|
public override string ToString() { return string.Format("ControlBoardDev on com{0}", controlBoardCfg.ComPortNr); }
|
|
|
|
public static void ResetStaticProperties() { }
|
|
|
|
ControlBoardCfg controlBoardCfg;
|
|
public Generic.IComponentCfg Cfg { get { return controlBoardCfg; } }
|
|
|
|
public string Name { get { return controlBoardCfg.Name; } }
|
|
|
|
|
|
///
|
|
/// Reference to the control board component
|
|
///
|
|
IControlCom controlCom;
|
|
|
|
/// <summary>
|
|
/// Emergency stop signal state updated by RunDevice().
|
|
/// 'modelessDlg' is notified about the changes and uses this information to change its visibility.
|
|
/// </summary>
|
|
//UiBridge.EmergencyStopEventArgs.State emergencyStopState;
|
|
|
|
|
|
///
|
|
/// Public read only wrappers for Elde software component fields
|
|
///
|
|
/// rvNr1 = 1 .. nrRegulValves (one based)
|
|
/// wmNr0 = 0 .. nrWaterMeters-1 (zero based)
|
|
/// tmpNr0 = 0 .. nrTempMeters-1 (zero based)
|
|
/// prsNr0 = 0 .. nrPressureMeters-1 (zero based)
|
|
///
|
|
public StatusP StatusP { get { return controlCom.StatusP; } }
|
|
public float ReferenceFreq { get { return controlCom.ReferenceFreq; } } /// In [Hz] 0..2500, nom.=2000
|
|
public int EtPulses(int wmNr0) { return controlCom.EtPulses(wmNr0); }
|
|
public int WMeterPulses(int wmNr0) { return controlCom.WMeterPulses(wmNr0); }
|
|
public int WMeterReference(int wmNr0) { return controlCom.WMeterReference(wmNr0); }
|
|
public uint RegulValveDAC { get { return controlCom.RegulValveDAC; } }
|
|
public float Pressure(int prsNr0) { return controlCom.Pressure(prsNr0); }
|
|
public float Temperature(int tmpNr0) { return controlCom.Temperature(tmpNr0); }
|
|
public RegulValveState RegulValveState(int rvNr1) { return (RegulValveState)controlCom.RegulValveState(rvNr1); }
|
|
public ulong RRoute { get { return controlCom.RRoute; } }
|
|
public uint DivTime { get { return controlCom.DivTime; } }
|
|
public float TTime { get { return controlCom.TTime; } }
|
|
public uint FmState { get { return controlCom.FmState; } }
|
|
public uint BeginState(int wmNr0) { return controlCom.BeginState(wmNr0); }
|
|
public float ReferenceFlow { get { return controlCom.ReferenceFlow; } }
|
|
public float RValvePosition(int rvNr1) { return controlCom.RValvePosition(rvNr1); }
|
|
public float DivSamples(int ms) { return controlCom.DivSamples(ms); }
|
|
public int ScopeSamples(int i, int j, int k) { return controlCom.ScopeSamples(i, j, k); }
|
|
public uint DigitalInputs { get { return controlCom.DigitalInputs; } }
|
|
public float AnalogInput(int adcNr0) { return controlCom.AnalogInput(adcNr0); }
|
|
public uint AnalogInputRaw(int adcNr0, int bank) { return controlCom.AnalogInputRaw(adcNr0, bank); } /// bank0=RV, bank1=Temp
|
|
public float ReferenceVolume { get { return controlCom.ReferenceVolume; } }
|
|
public float VyslExt(int wmNr0, int what) { return controlCom.VyslExt(wmNr0, what); }
|
|
|
|
/// <summary> Extracted from the StatusP in RunDeviceBefore </summary>
|
|
public bool EmergencyStop { get { return emergencyStop; } }
|
|
bool emergencyStop;
|
|
bool previousEmergencyStop;
|
|
|
|
/// <summary> State of valves sent out - buffered by the last SendCommand() </summary>
|
|
public ulong Route { get { return route; } }
|
|
|
|
ulong valvesToInvert; /// Route = valesToInvert ^ RequiredRouteWithoutInvertedVlaves
|
|
|
|
///
|
|
/// Initialization data updated by constructors of children components
|
|
/// and sent to 'controlCom2panel' by SendCalibData() method.
|
|
///
|
|
public uint[,] RegValveCalib = new uint[8, 2];
|
|
public byte[] MeretRS485Address = new byte[4];
|
|
public float[,] TempCalibData = new float[8, 5];
|
|
|
|
// Array length is the reference flowmeters count plus one
|
|
#if DN100
|
|
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
|
|
#elif MUNICH
|
|
public float[] EtCalib = new float[5] { 1, 1, 1, 1, 1 };
|
|
#elif FUZHOU150
|
|
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
|
|
#elif FUZHOU300
|
|
public float[] EtCalib = new float[6] { 1, 1, 1, 1, 1, 1 };
|
|
#endif
|
|
public uint[] DiverterEdge = new uint[2] { 50, 50 };
|
|
public uint[] BalanceRange = new uint[2];
|
|
|
|
///
|
|
/// Private values sent by the last SendCommand()
|
|
///
|
|
bool sendCommandFlag;
|
|
Command cmd;
|
|
int refNr;
|
|
ulong route;
|
|
int refPulses;
|
|
TestMethods testMethods;
|
|
float filterConstant;
|
|
float[] FMFreq;
|
|
int regConst;
|
|
int shortImp;
|
|
StopDevs stopDevs;
|
|
|
|
/// <summary>
|
|
/// Sets the power of the selected pump
|
|
/// </summary>
|
|
/// <param name="index">Pump index 0 .. 5, invalid pump index sets all pumps to 0%</param>
|
|
/// <param name="power">Power (0.0f .. 100.0f)</param>
|
|
public void SetFMFreq(int index, float power)
|
|
{
|
|
#if FUZHOU300
|
|
if ((FMFreq == null) || (FMFreq.Length != 6))
|
|
{
|
|
if (index == 0) FMFreq = new float[6] { power, 0, 0, 0, 0, 0 };
|
|
else if (index == 1) FMFreq = new float[6] { 0, power, 0, 0, 0, 0 };
|
|
else if (index == 2) FMFreq = new float[6] { 0, 0, power, 0, 0, 0 };
|
|
else if (index == 3) FMFreq = new float[6] { 0, 0, 0, power, 0, 0 };
|
|
else if (index == 4) FMFreq = new float[6] { 0, 0, 0, 0, power, 0 };
|
|
else if (index == 5) FMFreq = new float[6] { 0, 0, 0, 0, 0, power };
|
|
else FMFreq = new float[6] { 0, 0, 0, 0, 0, 0 };
|
|
}
|
|
else if(index >= 0 && index < 6)
|
|
{
|
|
FMFreq[index] = power;
|
|
}
|
|
#else
|
|
if (index == 0) FMFreq = new float[2] { power, 0 };
|
|
else if (index == 1) FMFreq = new float[2] { 0, power };
|
|
else FMFreq = new float[2] { 0, 0 };
|
|
#endif
|
|
}
|
|
|
|
public void UpdateWeights()
|
|
{
|
|
for (int i = 0; i < MettlerToledo.BalanceDev.BalancesCount; i++)
|
|
{
|
|
controlCom.SetWeight(i, MettlerToledo.BalanceDev.Masses[i]);
|
|
}
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Constructor
|
|
/// </summary>
|
|
public ControlBoardDev(ControlBoardCfg cfg, IList<Generic.IComponent> components)
|
|
{
|
|
if (cfg == null) throw new ArgumentNullException("cfg");
|
|
this.controlBoardCfg = cfg;
|
|
FMFreq = new float[6] { 0, 0, 0, 0, 0, 0 }; /// Nr. of pumps: Fuzhou150=2, Fuzhou300=6
|
|
emergencyStop = false;
|
|
previousEmergencyStop = false;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Specific pre-initialization for control board only
|
|
/// </summary>
|
|
/// <param name="ctrlBrdComponent"></param>
|
|
public void InitializeComponent(
|
|
#if DN100
|
|
ControlCom2VB.ControlCom2panel ctrlBrdComponent,
|
|
#elif MUNICH
|
|
ControlComponent3Munich.UserControl1 ctrlBrdComponent,
|
|
#elif FUZHOU150
|
|
ControlComponent3Munich.UserControl1 ctrlBrdComponent,
|
|
#elif FUZHOU300
|
|
ControlComponent3F300.UserControl1 ctrlBrdComponent,
|
|
#endif
|
|
ulong valvesToInvert,
|
|
float[] tankCapacities)
|
|
{
|
|
this.valvesToInvert = valvesToInvert;
|
|
this.route = valvesToInvert;
|
|
|
|
if (controlBoardCfg.DebugLevel == Entities.DebugMode.Simulate)
|
|
{
|
|
controlCom = new ControlComSim();
|
|
}
|
|
else
|
|
{
|
|
int cnt = Math.Min(BalanceRange.Length, tankCapacities.Length);
|
|
for (int i = 0; i < cnt; i++) BalanceRange[i] = (uint)tankCapacities[i];
|
|
controlCom = new ControlComWrap(ctrlBrdComponent);
|
|
}
|
|
}
|
|
|
|
/// <summary>Initialize this device</summary>
|
|
public void Initialize()
|
|
{
|
|
controlCom.SendCalibData(RegValveCalib,
|
|
MeretRS485Address,
|
|
controlBoardCfg.ComPortNr,
|
|
TempCalibData,
|
|
EtCalib,
|
|
DiverterEdge,
|
|
BalanceRange);
|
|
}
|
|
|
|
/// <summary>Run this device</summary>
|
|
public void RunDeviceBefore()
|
|
{
|
|
controlCom.RunDeviceBefore();
|
|
|
|
previousEmergencyStop = emergencyStop;
|
|
emergencyStop = (controlCom.StatusP & StatusP.EmgcyStopActive) != 0;
|
|
|
|
if (emergencyStop && !previousEmergencyStop)
|
|
{
|
|
Program.MainWnd.Invoke(new ShowEmergencyStopFormDlgt(ShowEmergencyStopForm));
|
|
}
|
|
else if (!emergencyStop && previousEmergencyStop)
|
|
{
|
|
UiBridge.Bridge.OnEmergencyStopChanged(this,UiBridge.EmergencyStopEventArgs.State.CloseForm);
|
|
}
|
|
|
|
if (emergencyStop)
|
|
{
|
|
/// SendCommand() arguments to clear the emergency stop state
|
|
sendCommandFlag = true;
|
|
this.cmd = Command.Stop;
|
|
this.stopDevs = StopDevs.All;
|
|
}
|
|
else
|
|
{
|
|
/// Reset all SendCommand() arguments
|
|
sendCommandFlag = false;
|
|
this.cmd = Command.None;
|
|
this.stopDevs = 0;
|
|
}
|
|
this.refNr = 0;
|
|
this.refPulses = 0;
|
|
this.testMethods = 0;
|
|
this.filterConstant = 0;
|
|
this.regConst = 0;
|
|
this.shortImp = 0;
|
|
}
|
|
|
|
/// <summary>Run this device</summary>
|
|
public void RunDeviceAfter()
|
|
{
|
|
if (sendCommandFlag)
|
|
{
|
|
controlCom.SendCommand(cmd, refNr, route, refPulses, testMethods,
|
|
filterConstant, FMFreq, regConst, shortImp, stopDevs);
|
|
}
|
|
|
|
controlCom.RunDeviceAfter();
|
|
}
|
|
|
|
/// <summary>Stop this device</summary>
|
|
public void StopDevice()
|
|
{
|
|
}
|
|
|
|
|
|
delegate void ShowEmergencyStopFormDlgt();
|
|
///
|
|
void ShowEmergencyStopForm()
|
|
{
|
|
(new TBF.Forms.EmergencyStopForm()).Show();
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Sends a command to the control board.
|
|
/// </summary>
|
|
/// <param name="cmd">See ControlBoard.Command enum</param>
|
|
/// <param name="refFlowmtrNr">Number of the etalon/reference (1..5)</param>
|
|
/// <param name="route">Route: 64-bit installation specific number</param>
|
|
/// <param name="totalRefPulses">kolko impulzov ma trvat skuska</param>
|
|
/// <param name="testMethods">See ControlBoard.TestMethods enum</param>
|
|
/// <param name="filterConstant">0 = No filtering (0..255)</param>
|
|
/// <param name="regConst">Coefficient used to control reg. valves (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 refFlowmtrNr, ulong route, int totalRefPulses, TestMethods testMethods,
|
|
float filterConstant, int regConst, int shortImp, StopDevs stopDevs)
|
|
{
|
|
this.cmd = cmd;
|
|
this.refNr = refFlowmtrNr;
|
|
this.route = route;
|
|
this.refPulses = totalRefPulses;
|
|
this.testMethods = testMethods;
|
|
this.filterConstant = filterConstant;
|
|
this.regConst = regConst;
|
|
this.shortImp = shortImp;
|
|
this.stopDevs = stopDevs;
|
|
|
|
sendCommandFlag = true;
|
|
}
|
|
|
|
public void SetValves(ulong valvesToOpen, ulong valvesToClose)
|
|
{
|
|
route = (((route ^ valvesToInvert) | valvesToOpen) & (~valvesToClose)) ^ valvesToInvert;
|
|
sendCommandFlag = true;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Regulation valves control.
|
|
/// </summary>
|
|
/// <param name="valveNo">Regulation 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>
|
|
/// <param name="stableTime">Stabilization time when setting the flow: 0=200ms, step 50ms, max. 1.5 sec.</param>
|
|
public void ValveMove(int valveNo, RegulValveMode valveMode, float[] valveValue, int stableTime)
|
|
{
|
|
controlCom.ValveMove(valveNo, valveMode, valveValue, stableTime);
|
|
}
|
|
|
|
|
|
/// <summary>
|
|
/// Open one valve and/or close one valve.
|
|
/// Events: ValvesSet
|
|
/// </summary>
|
|
/// <param name="valveOpen">Valve to be opened</param>
|
|
/// <param name="valveClose">Valve to be closed</param>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation SetValvesOp(IValve valveOpen, IValve valveClose)
|
|
{
|
|
return new Valve.SetValvesOp(this, valveOpen, valveClose);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Open and/or close multiple valves.
|
|
/// Events: ValvesSet
|
|
/// </summary>
|
|
/// <param name="valvesOpen">A list of valves to be opened</param>
|
|
/// <param name="valvesClose">A list of valves to be closed</param>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation SetValvesOp(IList<IValve> valvesOpen, IList<IValve> valvesClose)
|
|
{
|
|
return new Valve.SetValvesOp(this, valvesOpen, valvesClose);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Starts the measurement.
|
|
/// Events: MeasurementStarted
|
|
/// </summary>
|
|
/// <param name="flowMeter">Flow meter</param>
|
|
/// <param name="readers">An array of register readers</param>
|
|
/// <param name="refPulses">Number of reference pulses to complete the test</param>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation StartMeasurementOp(IFlowMeter flowMeter, int refPulses, TestMethods method, float filterConstant)
|
|
{
|
|
return new StartMeasurementOp(this, flowMeter, refPulses, method, filterConstant);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Queries th econtrol board whether the measurement was completed.
|
|
/// Events: MeasurementCompleted or None
|
|
/// </summary>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation QueryMeasurementEndOp()
|
|
{
|
|
return new QueryMeasurementEndOp(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Stop the previous control board operation (diverter, gate, etc.)
|
|
/// Events: PreviousStopped
|
|
/// </summary>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation StopPreviousOp()
|
|
{
|
|
return new StopPreviousOp(this);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Updates the tank drawing and weight value in Elde software component.
|
|
/// </summary>
|
|
/// <param name="weight">Current mass in [kg] or approx. volume in [l]</param>
|
|
/// <returns>Created operation</returns>
|
|
public IOperation UpdateTankWeightOp()
|
|
{
|
|
return new UpdateTankWeightOp(this);
|
|
}
|
|
}
|
|
}
|