diff --git a/TBF/Properties/AssemblyInfo.cs b/TBF/Properties/AssemblyInfo.cs
index ef5605a28..e05f7a9c7 100644
--- a/TBF/Properties/AssemblyInfo.cs
+++ b/TBF/Properties/AssemblyInfo.cs
@@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
// Build Number
// Revision
//
-[assembly: AssemblyVersion("2.28.1921.0")]
-[assembly: AssemblyFileVersion("2.28.1921.0")]
+[assembly: AssemblyVersion("2.28.1924.0")]
+[assembly: AssemblyFileVersion("2.28.1924.0")]
diff --git a/TBF/Rig/Modbus/TempControl/Novus/SetTemperatureSetpointOp.cs b/TBF/Rig/Modbus/TempControl/Novus/SetTemperatureSetpointOp.cs
index 5d5bb4fc1..ef30098a4 100644
--- a/TBF/Rig/Modbus/TempControl/Novus/SetTemperatureSetpointOp.cs
+++ b/TBF/Rig/Modbus/TempControl/Novus/SetTemperatureSetpointOp.cs
@@ -7,6 +7,16 @@ using TBF.Boxes;
namespace TBF.Rig.Modbus.TempControl.Novus
{
+ public enum SetpSource
+ {
+ TempArgument,
+ ProcParamA,
+ ProcParamB,
+ ProcParamC,
+ ProcParamD,
+ ProcParamE
+ }
+
public class SetTemperatureSetpointOp : IOperation
{
private static readonly ILog log = LogManager.GetLogger(typeof(SetTemperatureSetpointOp));
@@ -14,6 +24,7 @@ namespace TBF.Rig.Modbus.TempControl.Novus
/// Set by the constructor
readonly TControl tempControl;
+ readonly SetpSource spSrc;
readonly double temperature;
readonly Event eventDone;
@@ -22,24 +33,33 @@ namespace TBF.Rig.Modbus.TempControl.Novus
///
/// Temp. controller reference
/// Event to be returned by Run() when completed OK
- public SetTemperatureSetpointOp(TControl tempControl, double temperature, Event eventDone)
+ public SetTemperatureSetpointOp(TControl tempControl, SetpSource spSrc, double temperature, Event eventDone = Event.ConditionNotMet)
{
if (tempControl == null) throw new ArgumentNullException("tempControl");
this.tempControl = tempControl;
+ this.spSrc = spSrc;
this.temperature = temperature;
this.eventDone = eventDone;
log.Debug(this.ToString());
}
- public SetTemperatureSetpointOp(TControl tempControl, double temperature)
- : this(tempControl, temperature, Event.ConditionNotMet)
- {
- }
/// Start this operation
public void Start()
{
- tempControl.SetTemperatureSetpoint(temperature);
+ double selectedTemp;
+ switch (spSrc)
+ {
+ default:
+ case SetpSource.TempArgument: selectedTemp = temperature; break;
+ case SetpSource.ProcParamA: selectedTemp = tempControl.ProcParamA; break;
+ case SetpSource.ProcParamB: selectedTemp = tempControl.ProcParamB; break;
+ case SetpSource.ProcParamC: selectedTemp = tempControl.ProcParamC; break;
+ case SetpSource.ProcParamD: selectedTemp = tempControl.ProcParamD; break;
+ case SetpSource.ProcParamE: selectedTemp = tempControl.ProcParamE; break;
+ }
+
+ tempControl.SetTemperatureSetpoint(selectedTemp);
}
/// Run this operation
diff --git a/TBF/Rig/Modbus/TempControl/Novus/TControl.cs b/TBF/Rig/Modbus/TempControl/Novus/TControl.cs
index b31f461c1..af3d577be 100644
--- a/TBF/Rig/Modbus/TempControl/Novus/TControl.cs
+++ b/TBF/Rig/Modbus/TempControl/Novus/TControl.cs
@@ -19,14 +19,27 @@ namespace TBF.Rig.Modbus.TempControl.Novus
const UInt16 SetpointAddress = 0; /// Temperature setpoint address
const UInt16 ProcessValueAddress = 1; /// Actual temperature address
- const UInt16 Status1Address = 6; /// Status word 1 address
- const UInt16 FWVersionAddress = 7; /// Firmware version address
- const UInt16 ControllerIdAddress = 8; /// Controller ID address
- const UInt16 Status2Address = 9; /// Status word 2 address
- const UInt16 Status3Address = 10; /// Status word 3 address
+
+ const UInt16 N1200_FWVerAddr = 7; /// Firmware ver. address (N1200/N1200HC)
+ const UInt16 N1200_CtrlIdAddr = 8; /// Controller ID address (N1200/N1200HC)
+ const UInt16 N1200_Status1Addr = 6; /// Status word 1 address (N1200/N1200HC)
+ const UInt16 N1200_Status2Addr = 9; /// Status word 2 address (N1200/N1200HC)
+ const int N1200_WordsCount = 10;
+
+ const UInt16 N1040_FWVerAddr = 8; /// Firmware ver. address (N1040)
+ const UInt16 N1040_CtrlIdAddr = 9; /// Controller ID address (N1040)
+ const UInt16 N1040_Status1Addr = 12; /// Status word 1 address (N1040)
+ const UInt16 N1040_Status2Addr = 13; /// Status word 2 address (N1040)
+ const int N1040_WordsCount = 14;
readonly TControlCfg novusCfg;
+ public double ProcParamA { get { return novusCfg.ProcParams != null ? novusCfg.ProcParams.Temp_A : 0; } }
+ public double ProcParamB { get { return novusCfg.ProcParams != null ? novusCfg.ProcParams.Temp_B : 0; } }
+ public double ProcParamC { get { return novusCfg.ProcParams != null ? novusCfg.ProcParams.Temp_C : 0; } }
+ public double ProcParamD { get { return novusCfg.ProcParams != null ? novusCfg.ProcParams.Temp_D : 0; } }
+ public double ProcParamE { get { return novusCfg.ProcParams != null ? novusCfg.ProcParams.Temp_E : 0; } }
+
Common.Modbus modbus;
int ticketNumber; /// 0 .. number of devices registered for regular polling - 1
@@ -86,14 +99,43 @@ namespace TBF.Rig.Modbus.TempControl.Novus
Int16 status1;
Int16 status2;
- Int16 status3;
Int16 fwVersion;
Int16 controllerId;
double temperatureSetpoint;
double actualTemperature;
- bool isHeating { get { return (status2 & (1 << 11)) != 0; } } /// Output 1: Heating
- bool isCooling { get { return (status2 & (1 << 12)) != 0; } } /// Output 2: Cooling
+ bool isHeating
+ {
+ get
+ {
+ switch (novusCfg.Type)
+ {
+ case Type.N1200HC:
+ case Type.N1200:
+ return (status2 & (1 << 11)) != 0; /// Output 1 set
+ case Type.N1040:
+ default:
+ return false; /// isHeating info unknown
+ }
+ }
+ }
+
+ bool isCooling
+ {
+ get
+ {
+ switch (novusCfg.Type)
+ {
+ case Type.N1200HC:
+ case Type.N1200:
+ return (status2 & (1 << 12)) != 0; /// Output 2 set
+ case Type.N1040:
+ default:
+ return false; /// isCooling info unknown
+ }
+ }
+ }
+
bool isFahrenheit { get { return (status2 & (1 << 9)) != 0; } }
@@ -144,20 +186,22 @@ namespace TBF.Rig.Modbus.TempControl.Novus
{
log.InfoFormat("[{0}] received 5 bytes", Name);
}
- else if (telegram.Length == 27 && telegram[1] == (byte)Function.ReadHoldingRegisters && telegram[2] == 22)
+ else if ((novusCfg.Type == Type.N1200HC || novusCfg.Type == Type.N1200) &&
+ telegram.Length == 2 * N1200_WordsCount + 5 &&
+ telegram[1] == (byte)Function.ReadHoldingRegisters &&
+ telegram[2] == 2 * N1200_WordsCount)
{
- Int16[] values = new Int16[11];
+ Int16[] values = new Int16[N1200_WordsCount];
for (int i = 0; i < values.Length; i++)
{
values[i] = (Int16)(256 * telegram[2 * i + 3] + telegram[2 * i + 4]
- ((telegram[2 * i + 3] & 0x80) != 0 ? 65536 : 0));
}
- status1 = values[Status1Address];
- status2 = values[Status2Address];
- status3 = values[Status3Address];
- fwVersion = values[FWVersionAddress];
- controllerId = values[ControllerIdAddress];
+ status1 = values[N1200_Status1Addr];
+ status2 = values[N1200_Status2Addr];
+ fwVersion = values[N1200_FWVerAddr];
+ controllerId = values[N1200_CtrlIdAddr];
double setpointCorF = (double)values[SetpointAddress] * 0.1;
temperatureSetpoint = isFahrenheit ? Units.ConvertFrom(Unit.F, setpointCorF) : setpointCorF;
@@ -173,9 +217,44 @@ namespace TBF.Rig.Modbus.TempControl.Novus
StateMachine.ControlBoard.SetReservoirTemp(2 * (novusCfg.ReservoirNr - 1) + 1, setpointStr, Convert.ToSingle(temperatureSetpoint));
log.InfoFormat("[{0}] setpoint = {1} temperature = {2}", Name, temperatureSetpoint, actualTemperature);
- log.InfoFormat("[{0}] s1=0x{1} s2=0x{2} s3=0x{3} fw={4} id={5}",
- Name, status1.ToString("X4"), status2.ToString("X4"), status3.ToString("X4"),
- fwVersion, controllerId == 18 ? "N1200HC" : controllerId == 48 ? "N1200" : "unknonw");
+ log.InfoFormat("[{0}] s1=0x{1} s2=0x{2} fw={3} id={4}",
+ Name, status1.ToString("X4"), status2.ToString("X4"), fwVersion,
+ controllerId == 18 ? "N1200HC" : controllerId == 48 ? "N1200" : "unknown");
+ }
+ else if (novusCfg.Type == Type.N1040 &&
+ telegram.Length == 2 * N1040_WordsCount + 5 &&
+ telegram[1] == (byte)Function.ReadHoldingRegisters &&
+ telegram[2] == 2 * N1040_WordsCount)
+ {
+ Int16[] values = new Int16[N1040_WordsCount];
+ for (int i = 0; i < values.Length; i++)
+ {
+ values[i] = (Int16)(256 * telegram[2 * i + 3] + telegram[2 * i + 4]
+ - ((telegram[2 * i + 3] & 0x80) != 0 ? 65536 : 0));
+ }
+
+ status1 = values[N1040_Status1Addr];
+ status2 = values[N1040_Status2Addr];
+ fwVersion = values[N1040_FWVerAddr];
+ controllerId = values[N1040_CtrlIdAddr];
+
+ double setpointCorF = (double)values[SetpointAddress] * 0.1;
+ temperatureSetpoint = isFahrenheit ? Units.ConvertFrom(Unit.F, setpointCorF) : setpointCorF;
+ string setpointStr = string.Format(novusCfg.SetpFormat, Units.ConvertTo(novusCfg.SetpUnit, temperatureSetpoint));
+
+ double temperatureCorF = (double)values[ProcessValueAddress] * 0.1;
+ actualTemperature = isFahrenheit ? Units.ConvertFrom(Unit.F, temperatureCorF) : temperatureCorF;
+ string temperatureStr = string.Format(novusCfg.MsrdFormat, Units.ConvertTo(novusCfg.MsrdUnit, actualTemperature));
+
+ novusDataValid = true;
+
+ StateMachine.ControlBoard.SetReservoirTemp(2 * (novusCfg.ReservoirNr - 1), temperatureStr, Convert.ToSingle(actualTemperature));
+ StateMachine.ControlBoard.SetReservoirTemp(2 * (novusCfg.ReservoirNr - 1) + 1, setpointStr, Convert.ToSingle(temperatureSetpoint));
+
+ log.InfoFormat("[{0}] setpoint = {1} temperature = {2}", Name, temperatureSetpoint, actualTemperature);
+ log.InfoFormat("[{0}] s1=0x{1} s2=0x{2} fw={3} id={4}",
+ Name, status1.ToString("X4"), status2.ToString("X4"), fwVersion,
+ controllerId == 66 ? "N1040" : "unknown");
}
else
{
@@ -200,8 +279,16 @@ namespace TBF.Rig.Modbus.TempControl.Novus
if (DebugLevel != DebugMode.Simulate && DebugLevel != DebugMode.FailureDuringOperation
&& (StateMachine.Time % 3 == novusCfg.ReservoirNr - 1))
{
- /// Read setpoint, PV (actual temperature), status1, status2, status3, FW version etc.
- SendValueToNovus(Function.ReadHoldingRegisters, 0, 11);
+ if (novusCfg.Type == Type.N1200HC || novusCfg.Type == Type.N1200)
+ {
+ /// Read SP (setpoint), PV (actual temperature), status1, status2, status3, FW version etc.
+ SendValueToNovus(Function.ReadHoldingRegisters, 0, N1200_WordsCount);
+ }
+ else if (novusCfg.Type == Type.N1040)
+ {
+ /// Read SP (setpoint) and PV (actual temperature)
+ SendValueToNovus(Function.ReadHoldingRegisters, 0, N1040_WordsCount);
+ }
}
}
@@ -263,14 +350,14 @@ namespace TBF.Rig.Modbus.TempControl.Novus
return actualTemperature;
}
- ///
- /// Events: SetOpututsDone, Error
- ///
- /// SetOutputsOp instance reference casted to IOperaton
- public IOperation SetTemperatureSetpointOp(double temperature)
- {
- return new SetTemperatureSetpointOp(this, temperature);
- }
+ ///
+ /// Events: SetOpututsDone, Error
+ ///
+ /// SetOutputsOp instance reference casted to IOperaton
+ public IOperation SetTemperatureSetpointOp(double temperature)
+ {
+ return new SetTemperatureSetpointOp(this, SetpSource.TempArgument, temperature);
+ }
public IOperation ReadTempOp(ref DoubleBox temp)
{
@@ -329,11 +416,11 @@ namespace TBF.Rig.Modbus.TempControl.Novus
void CreateConditions(bool createOps)
{
ClearConditions();
- AddCondition("Set temperature setpoint A", createOps, SetTemperatureSetpointOp(novusCfg.ProcParams.Temp_A));
- AddCondition("Set temperature setpoint B", createOps, SetTemperatureSetpointOp(novusCfg.ProcParams.Temp_B));
- AddCondition("Set temperature setpoint C", createOps, SetTemperatureSetpointOp(novusCfg.ProcParams.Temp_C));
- AddCondition("Set temperature setpoint D", createOps, SetTemperatureSetpointOp(novusCfg.ProcParams.Temp_D));
- AddCondition("Set temperature setpoint E", createOps, SetTemperatureSetpointOp(novusCfg.ProcParams.Temp_E));
+ AddCondition(string.Format("Set {0} setpoint A", Name), createOps, new SetTemperatureSetpointOp(this, SetpSource.ProcParamA, 0));
+ AddCondition(string.Format("Set {0} setpoint B", Name), createOps, new SetTemperatureSetpointOp(this, SetpSource.ProcParamB, 0));
+ AddCondition(string.Format("Set {0} setpoint C", Name), createOps, new SetTemperatureSetpointOp(this, SetpSource.ProcParamC, 0));
+ AddCondition(string.Format("Set {0} setpoint D", Name), createOps, new SetTemperatureSetpointOp(this, SetpSource.ProcParamD, 0));
+ AddCondition(string.Format("Set {0} setpoint E", Name), createOps, new SetTemperatureSetpointOp(this, SetpSource.ProcParamE, 0));
}
}
}
diff --git a/TBF/Rig/Modbus/TempControl/Novus/TControlCfg.cs b/TBF/Rig/Modbus/TempControl/Novus/TControlCfg.cs
index 8cc1745eb..1a732a503 100644
--- a/TBF/Rig/Modbus/TempControl/Novus/TControlCfg.cs
+++ b/TBF/Rig/Modbus/TempControl/Novus/TControlCfg.cs
@@ -12,6 +12,14 @@ using TBF.Rig.Generic;
namespace TBF.Rig.Modbus.TempControl.Novus
{
+ public enum Type
+ {
+ N1200HC,
+ N1200,
+ N1040,
+ Count
+ }
+
public class TControlCfg : ComponentCfgBase, IChildComponentCfg, IParamsProvider
{
public static XmlSerializer Serializer = XmlSerializer.FromTypes(new[] { typeof(TControlCfg) })[0];
@@ -28,15 +36,16 @@ namespace TBF.Rig.Modbus.TempControl.Novus
/// Serialized parameters
///
public int ModbusAddress; /// 0: 1..254
- public string MsrdFormat { get; set; } /// 1
- public Unit MsrdUnit { get; set; } /// 2
+ public Type Type; /// 1: N1200HC, N1200 or N1040
+ public string MsrdFormat { get; set; } /// 2
+ public Unit MsrdUnit { get; set; } /// 3
public double MsrdValLimLo { get; set; }
public double MsrdValLimHi { get; set; }
- public string SetpFormat { get; set; } /// 3
- public Unit SetpUnit { get; set; } /// 4
- public double SetpStep { get; set; } /// 5
- public bool RoundToSetpStep { get; set; } /// 6
- public int ReservoirNr { get; set; } /// 7
+ public string SetpFormat { get; set; } /// 4
+ public Unit SetpUnit { get; set; } /// 5
+ public double SetpStep { get; set; } /// 6
+ public bool RoundToSetpStep { get; set; } /// 7
+ public int ReservoirNr { get; set; } /// 8
/// Procedure parameters
@@ -66,6 +75,7 @@ namespace TBF.Rig.Modbus.TempControl.Novus
Name = "Novus";
ParentName = "Modbus";
ModbusAddress = 49;
+ Type = Novus.Type.N1200HC;
MsrdFormat = "{0:F1} °C";
MsrdUnit = Unit.C;
MsrdValLimLo = 5;
@@ -80,13 +90,14 @@ namespace TBF.Rig.Modbus.TempControl.Novus
string[] paramNames = new string[]
{
"Modbus address", /// 0
- "Measured temperature format", /// 1
- "Unit of measured temperature", /// 2
- "Setpoint format", /// 3
- "Unit of temperature setpoint", /// 4
- "Setpoint step", /// 5
- "Round to setpoint step", /// 6
- "Reservoir nr. (1-based)", /// 7
+ "Type", /// 1
+ "Measured temperature format", /// 2
+ "Unit of measured temperature", /// 3
+ "Setpoint format", /// 4
+ "Unit of temperature setpoint", /// 5
+ "Setpoint step", /// 6
+ "Round to setpoint step", /// 7
+ "Reservoir nr. (1-based)", /// 8
};
public string ParamName(int i) { return paramNames[i]; }
public int ParamsCount() { return paramNames.Length; }
@@ -95,10 +106,14 @@ namespace TBF.Rig.Modbus.TempControl.Novus
{
switch (i)
{
- case 2:
- case 4:
+ case 1:
+ var list = new List();
+ for (Novus.Type t = 0; t < Novus.Type.Count; t++) list.Add(t.ToString());
+ return list;
+ case 3:
+ case 5:
return new string[] { "°C", "°F", "K" };
- case 6:
+ case 7:
return new string[] { Strings.yes, Strings.no };
default:
return null;
@@ -111,15 +126,17 @@ namespace TBF.Rig.Modbus.TempControl.Novus
switch (i)
{
case 0: return ModbusAddress.ToString();
- case 1: return MsrdFormat;
- case 2: return (MsrdUnit == Unit.K) ? "K" : (MsrdUnit == Unit.F) ? "°F" : "°C";
- case 3: return SetpFormat;
- case 4: return (SetpUnit == Unit.K) ? "K" : (SetpUnit == Unit.F) ? "°F" : "°C";
- case 5: return SetpStep.ToString();
- case 6: return RoundToSetpStep ? Strings.yes : Strings.no;
- case 7: return ReservoirNr.ToString();
+ case 1: return Type.ToString();
+ case 2: return MsrdFormat;
+ case 3: return (MsrdUnit == Unit.K) ? "K" : (MsrdUnit == Unit.F) ? "°F" : "°C";
+ case 4: return SetpFormat;
+ case 5: return (SetpUnit == Unit.K) ? "K" : (SetpUnit == Unit.F) ? "°F" : "°C";
+ case 6: return SetpStep.ToString();
+ case 7: return RoundToSetpStep ? Strings.yes : Strings.no;
+ case 8: return ReservoirNr.ToString();
default:
- return string.Format("{0}({1}) address={2}", Name, string.IsNullOrEmpty(ParentName) ? "-" : ParentName, ModbusAddress);
+ return string.Format("{0}({1}) address = {2}, type = {3}, reservoir = {4}",
+ Name, string.IsNullOrEmpty(ParentName) ? "-" : ParentName, ModbusAddress, Type, ReservoirNr);
}
}
@@ -128,19 +145,29 @@ namespace TBF.Rig.Modbus.TempControl.Novus
switch (i)
{
case 0: ModbusAddress = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
- case 1: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
- case 2: MsrdUnit = (str == "°K" || str == "K") ? Unit.K
+ case 1:
+ for (Novus.Type t = 0; t < Novus.Type.Count; t++)
+ {
+ if (t.ToString() == str)
+ {
+ Type = t;
+ return CfgUpdateFlags.RestartRqrd;
+ }
+ }
+ return CfgUpdateFlags.None;
+ case 2: MsrdFormat = str; return CfgUpdateFlags.RestartRqrd;
+ case 3: MsrdUnit = (str == "°K" || str == "K") ? Unit.K
: (str == "°F" || str == "F") ? Unit.F
: Unit.C;
return CfgUpdateFlags.RestartRqrd;
- case 3: SetpFormat = str; return CfgUpdateFlags.RestartRqrd;
- case 4: SetpUnit = (str == "°K" || str == "K") ? Unit.K
+ case 4: SetpFormat = str; return CfgUpdateFlags.RestartRqrd;
+ case 5: SetpUnit = (str == "°K" || str == "K") ? Unit.K
: (str == "°F" || str == "F") ? Unit.F
: Unit.C;
return CfgUpdateFlags.RestartRqrd;
- case 5: SetpStep = Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd;
- case 6: RoundToSetpStep = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd;
- case 7: ReservoirNr = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
+ case 6: SetpStep = Utils.ParseUDouble(str); return CfgUpdateFlags.RestartRqrd;
+ case 7: RoundToSetpStep = (str == Strings.yes); return CfgUpdateFlags.RestartRqrd;
+ case 8: ReservoirNr = int.Parse(str); return CfgUpdateFlags.RestartRqrd;
default: return CfgUpdateFlags.None;
}
}
@@ -154,22 +181,29 @@ namespace TBF.Rig.Modbus.TempControl.Novus
switch (i)
{
case 0:
+ /// ModbusAddress
if (int.TryParse(str, out idummy) && idummy >= 1 && idummy <= 254) return true;
break;
case 1:
- case 3:
- return true;
+ case 7:
+ /// Type, RoundToSetpStep (yes/no)
+ if (ParamValues(i).Contains(str)) return true;
+ break;
case 2:
case 4:
- if (str == "°K" || str == "K" || str == "°F" || str == "F" || str == "°C" || str == "C") return true;
- break;
+ /// MsrdFormat, SetpFormat
+ return true;
+ case 3:
case 5:
- if (Utils.TryParseUDouble(str, out ddummy)) return true;
+ /// MsrdUnit, SetpUnit
+ if (ParamValues(i).Contains(str) || str == "C" || str == "F" || str == "°K") return true;
break;
case 6:
- if (str == Strings.yes || str == Strings.no) return true;
+ /// SetpStep
+ if (Utils.TryParseUDouble(str, out ddummy)) return true;
break;
- case 7:
+ case 8:
+ /// ReservoirNr
if (int.TryParse(str, out idummy) && idummy >= 1 && idummy <= 10) return true;
break;
default:
@@ -185,6 +219,7 @@ namespace TBF.Rig.Modbus.TempControl.Novus
{
prms.ParentName = ParentName;
prms.ModbusAddress = ModbusAddress;
+ prms.Type = Type;
prms.MsrdFormat = MsrdFormat;
prms.MsrdUnit = MsrdUnit;
prms.MsrdValLimLo = MsrdValLimLo;