Modbus modified, UniCB Init. modified, RunDeviceAfter() called in reversed order, ver. 3.1.1597
This commit is contained in:
parent
ff70a11cad
commit
d7e65ff04b
@ -47,6 +47,21 @@ namespace Common
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Calculates the CRC from a data telegram (an array of bytes).
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>Calculated CRC</returns>
|
||||
public static UInt16 CalculateTelegramCRC(int offset, byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
int len = (enforcedLen != 0) ? Math.Min(enforcedLen, data.Length - offset) : data.Length - offset;
|
||||
UInt16 crc = crcSeed;
|
||||
for (int i = 0; i < len - 2; i++) UpdateCRC(data[offset + i], ref crc);
|
||||
return crc;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function modifies the last 2 bytes in the message buffer
|
||||
/// by the CRC calculated from the remaining first (Lenght - 2) bytes.
|
||||
@ -85,6 +100,26 @@ namespace Common
|
||||
return (data[len - 2] == (byte)(crc & 0xFF)) && (data[len - 1] == (byte)(crc >> 8));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This function compares the last 2 bytes in the message buffer
|
||||
/// with the CRC calculated from the remaining first (Lenght - 2) bytes.
|
||||
/// A complete telegram including two bytes reserved for the CRC
|
||||
/// must be supplied as an argument.
|
||||
/// </summary>
|
||||
/// <param name="data">Data telegram</param>
|
||||
/// <returns>true if the CRC in the telegram is correct</returns>
|
||||
public static bool VerifyTelegramCRC(int offset, byte[] data, int enforcedLen = 0)
|
||||
{
|
||||
if (data == null || data.Length == 0 || enforcedLen > data.Length - offset) return false;
|
||||
|
||||
int len = (enforcedLen != 0) ? enforcedLen : data.Length - offset;
|
||||
if (len < 2) return false;
|
||||
|
||||
UInt16 crc = CalculateTelegramCRC(offset, data, len);
|
||||
|
||||
return (data[offset + len - 2] == (byte)(crc & 0xFF)) && (data[offset + len - 1] == (byte)(crc >> 8));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
|
||||
@ -29,5 +29,5 @@ using System.Runtime.InteropServices;
|
||||
// Build Number
|
||||
// Revision
|
||||
//
|
||||
[assembly: AssemblyVersion("3.1.1643.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.1643.0")]
|
||||
[assembly: AssemblyVersion("3.1.1597.0")]
|
||||
[assembly: AssemblyFileVersion("3.1.1597.0")]
|
||||
|
||||
@ -179,12 +179,6 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
scopeAnalyzerData = null;
|
||||
switchCounterData = null;
|
||||
|
||||
serialPort = null;
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
rcvdData = new byte[BUFFER_SIZE];
|
||||
cumulativeSums = new int[BUFFER_SIZE];
|
||||
rcvdBytesCount = 0;
|
||||
|
||||
routeMask = 0;
|
||||
for (int i = 0; i < 128; i++)
|
||||
{
|
||||
@ -194,19 +188,6 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
}
|
||||
}
|
||||
|
||||
TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args)
|
||||
{
|
||||
UInt128 mask = ((UInt128)1) << args.BitNr;
|
||||
if ((benchModelRoute & mask) == 0)
|
||||
{
|
||||
benchModelRoute |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
benchModelRoute &= (~mask);
|
||||
}
|
||||
};
|
||||
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
|
||||
@ -233,12 +214,30 @@ namespace TBF.Rig.ControlBoard.Uni
|
||||
return;
|
||||
}
|
||||
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
rcvdData = new byte[BUFFER_SIZE];
|
||||
cumulativeSums = new int[BUFFER_SIZE];
|
||||
rcvdBytesCount = 0;
|
||||
|
||||
serialPort = new SerialPort(comPort, 9600, Parity.None, 8, StopBits.One);
|
||||
serialPort.DtrEnable = true;
|
||||
serialPort.WriteTimeout = 4000;
|
||||
serialPort.ParityReplace = 0xFF;
|
||||
serialPort.Open();
|
||||
|
||||
TBF.UiBridge.Bridge.RouteChangeHandler += delegate(object sndr, TBF.UiBridge.RouteChangeArgs args)
|
||||
{
|
||||
UInt128 mask = ((UInt128)1) << args.BitNr;
|
||||
if ((benchModelRoute & mask) == 0)
|
||||
{
|
||||
benchModelRoute |= mask;
|
||||
}
|
||||
else
|
||||
{
|
||||
benchModelRoute &= (~mask);
|
||||
}
|
||||
};
|
||||
|
||||
log.FatalFormat("{0} - Device successfully initialized", Name);
|
||||
}
|
||||
|
||||
|
||||
@ -27,5 +27,18 @@ namespace TBF.Rig.GenericDevices
|
||||
void SendMessage(byte modbusAddress, byte function, ushort dataAddress, ushort dataCount);
|
||||
|
||||
Queue<byte[]>[] ReceivedTelegrams { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Registers a modbus device for scheduled polling
|
||||
/// </summary>
|
||||
/// <returns>Ticket numeber to be used as IsMyTurn() argumenr</returns>
|
||||
int RegisterForPolling();
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the registered device should do polling now
|
||||
/// </summary>
|
||||
/// <param name="ticketNr">Ticket number in range 1 .. registered devs.count returned by RegisterForPolling()</param>
|
||||
/// <returns>true when yes</returns>
|
||||
bool IsMyTurn(int ticketNr);
|
||||
}
|
||||
}
|
||||
|
||||
@ -74,9 +74,10 @@ namespace TBF.Rig.Modbus.Ambient.Comet
|
||||
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
|
||||
int msrmntTimeStamp;
|
||||
|
||||
public Ambient()
|
||||
{
|
||||
}
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
|
||||
public Ambient() { }
|
||||
|
||||
/// <summary>
|
||||
/// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
|
||||
@ -106,6 +107,7 @@ namespace TBF.Rig.Modbus.Ambient.Comet
|
||||
}
|
||||
|
||||
msrmntState = MsrmntState.Busy;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
|
||||
log.FatalFormat("Successfully initialized device {0}", ToString());
|
||||
}
|
||||
@ -143,8 +145,13 @@ namespace TBF.Rig.Modbus.Ambient.Comet
|
||||
log.InfoFormat("Ambient: temperature = {0:F1} C, humidity = {1:F1} %, pressure = {2:F0} mbar", temperature, humidity, 1000 * pressure);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((StateMachine.Time % 10) == (ambientCfg.ModbusAddress % 10)) /// Each 10 seconds
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (ambientCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
ambientCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
/// Read four registers: 0x31, 0x32, 0x33, 0x34
|
||||
UInt16 regAddr = 0x0030; /// register addr. = 0x31 (Modbus!)
|
||||
@ -163,7 +170,6 @@ namespace TBF.Rig.Modbus.Ambient.Comet
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
@ -27,10 +27,14 @@ namespace TBF.Rig.Modbus.Common
|
||||
|
||||
const int MinTelegramLen = 4;
|
||||
|
||||
private readonly ModbusCfg modbusCommonCfg;
|
||||
private readonly ModbusCfg modbusCfg;
|
||||
|
||||
/// Private fields
|
||||
SerialPort serialPort;
|
||||
const int BUFFER_SIZE = 1000; /// Size of input buffers
|
||||
byte[] buffer; /// Buffer for data received in one attempt in RunDeviceBefore()
|
||||
byte[] rcvdData; /// Buffer for all recevied but nut processed data. May contain data from several read attempts
|
||||
int rcvdBytesCount; /// Count of valid bytes in rcvdData buffer
|
||||
DateTime lastSerialPortWrite;
|
||||
bool initialRunDeviceCommComplete;
|
||||
|
||||
@ -42,9 +46,10 @@ namespace TBF.Rig.Modbus.Common
|
||||
|
||||
Queue<byte[]> telegramsToSend;
|
||||
|
||||
public Modbus()
|
||||
{
|
||||
}
|
||||
int registeredDevicesCount; /// Number of devices registered for poling
|
||||
|
||||
|
||||
public Modbus() { }
|
||||
|
||||
/// <summary>
|
||||
/// Ambient temperature / humidity / pressure meter 'Greco' connected via serial interface (RS232)
|
||||
@ -53,36 +58,37 @@ namespace TBF.Rig.Modbus.Common
|
||||
public Modbus(Generic.IComponentCfg cfg)
|
||||
: base(cfg)
|
||||
{
|
||||
receivedTelegrams = new Queue<byte[]>[256];
|
||||
for (int i = 0; i < receivedTelegrams.Length; i++)
|
||||
{
|
||||
receivedTelegrams[i] = new Queue<byte[]>();
|
||||
}
|
||||
telegramsToSend = new Queue<byte[]>();
|
||||
|
||||
serialPort = null;
|
||||
modbusCommonCfg = cfg as ModbusCfg;
|
||||
modbusCfg = cfg as ModbusCfg;
|
||||
log.Warn(this.ToString());
|
||||
}
|
||||
|
||||
~Modbus()
|
||||
{
|
||||
}
|
||||
|
||||
public void Initialize()
|
||||
{
|
||||
if (modbusCommonCfg.DebugLevel == DebugMode.Simulate)
|
||||
receivedTelegrams = new Queue<byte[]>[256];
|
||||
for (int i = 0; i < receivedTelegrams.Length; i++)
|
||||
{
|
||||
receivedTelegrams[i] = new Queue<byte[]>();
|
||||
}
|
||||
telegramsToSend = new Queue<byte[]>();
|
||||
|
||||
if (modbusCfg.DebugLevel == DebugMode.Simulate)
|
||||
{
|
||||
serialPort = null;
|
||||
log.FatalFormat("{0} - Device simulated", Name);
|
||||
return;
|
||||
}
|
||||
|
||||
string comPortName = "COM" + modbusCommonCfg.ComPortNr.ToString();
|
||||
serialPort = new SerialPort(comPortName, modbusCommonCfg.BaudRate, modbusCommonCfg.Parity, modbusCommonCfg.DataBits, modbusCommonCfg.StopBits);
|
||||
serialPort.Handshake = modbusCommonCfg.Handshake;
|
||||
buffer = new byte[BUFFER_SIZE];
|
||||
rcvdData = new byte[BUFFER_SIZE];
|
||||
rcvdBytesCount = 0;
|
||||
|
||||
string comPortName = "COM" + modbusCfg.ComPortNr.ToString();
|
||||
serialPort = new SerialPort(comPortName, modbusCfg.BaudRate, modbusCfg.Parity, modbusCfg.DataBits, modbusCfg.StopBits);
|
||||
serialPort.Handshake = modbusCfg.Handshake;
|
||||
serialPort.Open();
|
||||
|
||||
registeredDevicesCount = 0;
|
||||
|
||||
//stopWorkerThread = false;
|
||||
//workerThread = new Thread(Worker);
|
||||
//workerThread.Start();
|
||||
@ -93,6 +99,27 @@ namespace TBF.Rig.Modbus.Common
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Registers a modbus device for scheduled polling
|
||||
/// </summary>
|
||||
/// <returns>Ticket numeber to be used as IsMyTurn() argumenr</returns>
|
||||
public int RegisterForPolling()
|
||||
{
|
||||
registeredDevicesCount++;
|
||||
return registeredDevicesCount; /// 1 .. number of registered devices
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the registered device should do polling now
|
||||
/// </summary>
|
||||
/// <param name="ticketNr">Ticket number in range 1 .. registered devs.count returned by RegisterForPolling()</param>
|
||||
/// <returns>true when yes</returns>
|
||||
public bool IsMyTurn(int ticketNr)
|
||||
{
|
||||
return (StateMachine.Time % registeredDevicesCount == ticketNr - 1);
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Send an arbitrary modbus message.
|
||||
/// When the message length is N, however only bytes 1..N-2 have to be set.
|
||||
@ -189,69 +216,92 @@ namespace TBF.Rig.Modbus.Common
|
||||
/// <summary>Run this device</summary>
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
/// Create 'dataToProcess' buffer with all received bytes
|
||||
int nrBytes;
|
||||
if (serialPort == null || (nrBytes = serialPort.BytesToRead) < MinTelegramLen) return;
|
||||
byte[] dataToProcess = new byte[nrBytes];
|
||||
serialPort.Read(dataToProcess, 0, nrBytes);
|
||||
if (modbusCfg.DebugLevel != DebugMode.Normal || serialPort == null || !serialPort.IsOpen) return;
|
||||
|
||||
while (dataToProcess.Length >= MinTelegramLen)
|
||||
/// Read new received bytes and append them to a buffer
|
||||
int bytesCount = serialPort.BytesToRead;
|
||||
if (bytesCount > 0)
|
||||
{
|
||||
for (int candidateLen = MinTelegramLen; candidateLen <= dataToProcess.Length; candidateLen++)
|
||||
bytesCount = serialPort.Read(buffer, 0, Math.Min(bytesCount, BUFFER_SIZE));
|
||||
}
|
||||
///
|
||||
string st = string.Format("{0}", Name, Telegram.LogTelegram("Received data ", buffer, 0, bytesCount));
|
||||
Debug.WriteLine(st);
|
||||
log.Debug(st);
|
||||
///
|
||||
for (int i = 0; i < bytesCount && rcvdBytesCount < BUFFER_SIZE; i++, rcvdBytesCount++)
|
||||
{
|
||||
rcvdData[rcvdBytesCount] = buffer[i];
|
||||
}
|
||||
|
||||
/// Try to detect various kinds of data in rcvdData buffer in a loop, start at offset 0
|
||||
int offset = 0;
|
||||
int lastValidOffset = 0; /// Offset of the first byte after the last successfully parsed frame
|
||||
do
|
||||
{
|
||||
bool anyProcessed = false;
|
||||
|
||||
if (offset + 28 <= rcvdBytesCount &&
|
||||
rcvdData[offset] == '\r' &&
|
||||
rcvdData[offset + 1] == '\n' &&
|
||||
rcvdData[offset + 3] == 28 &&
|
||||
rcvdData[offset + 5] == 2)
|
||||
{
|
||||
if (candidateLen == 28 &&
|
||||
dataToProcess[0] == '\r' &&
|
||||
dataToProcess[1] == '\n' &&
|
||||
dataToProcess[3] == 28 &&
|
||||
dataToProcess[5] == 2)
|
||||
int sum = 0;
|
||||
for (int i = offset; i < offset + 27; i++) sum += rcvdData[i];
|
||||
///
|
||||
if (rcvdData[offset + 27] == (sum & 0xFF))
|
||||
{
|
||||
int sum = 0;
|
||||
for (int i = 0; i < 27; i++) sum += dataToProcess[i];
|
||||
///
|
||||
if (dataToProcess[27] == (sum & 0xFF))
|
||||
{
|
||||
/// Split data in dataToProcess buffer into the verified telegram and newly created dataToProcess
|
||||
byte[] receivedTelegram = dataToProcess.Take<byte>(candidateLen).ToArray<byte>();
|
||||
dataToProcess = dataToProcess.Skip<byte>(candidateLen).ToArray<byte>();
|
||||
/// Copy data to a created telegram
|
||||
byte[] receivedTelegram = new byte[28];
|
||||
for (int i = 0; i < 28; i++) receivedTelegram[i] = rcvdData[offset + i];
|
||||
|
||||
/// Enqueue
|
||||
receivedTelegrams[0].Enqueue(receivedTelegram);
|
||||
/// Enqueue
|
||||
receivedTelegrams[0].Enqueue(receivedTelegram);
|
||||
|
||||
string s = string.Format("{0} - {1} queue size={2}", Name, Telegram.LogTelegram("Received message ", receivedTelegram), receivedTelegrams[0].Count);
|
||||
Debug.WriteLine(s);
|
||||
log.Debug(s);
|
||||
break; /// Quit for loop
|
||||
}
|
||||
string s = string.Format("{0} queue size={1}", Telegram.LogTelegram("Received message ", receivedTelegram), receivedTelegrams[0].Count);
|
||||
Debug.WriteLine(s);
|
||||
log.Debug(s);
|
||||
offset += 28;
|
||||
lastValidOffset = offset;
|
||||
anyProcessed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (Telegram.VerifyTelegramCRC(dataToProcess, candidateLen))
|
||||
for (int candidateLen = 4; candidateLen <= rcvdBytesCount - offset; candidateLen++)
|
||||
{
|
||||
if (Telegram.VerifyTelegramCRC(offset, rcvdData, candidateLen))
|
||||
{
|
||||
/// A valid telegram found in dataToProcess buffer
|
||||
|
||||
/// Split data in dataToProcess buffer into the verified telegram and newly created dataToProcess
|
||||
byte[] receivedTelegram = dataToProcess.Take<byte>(candidateLen).ToArray<byte>();
|
||||
dataToProcess = dataToProcess.Skip<byte>(candidateLen).ToArray<byte>();
|
||||
/// Copy data to a created telegram
|
||||
byte[] receivedTelegram = new byte[candidateLen];
|
||||
for (int i = 0; i < candidateLen; i++) receivedTelegram[i] = rcvdData[offset + i];
|
||||
|
||||
/// Enqueue
|
||||
int deviceAddress = receivedTelegram[0];
|
||||
receivedTelegrams[deviceAddress].Enqueue(receivedTelegram);
|
||||
|
||||
string s = string.Format("{0} - {1} queue size={2}", Name, Telegram.LogTelegram("Received message ", receivedTelegram), receivedTelegrams[deviceAddress].Count);
|
||||
string s = string.Format("{0} queue size={1}", Telegram.LogTelegram("Received message ", receivedTelegram), receivedTelegrams[deviceAddress].Count);
|
||||
Debug.WriteLine(s);
|
||||
log.Debug(s);
|
||||
break; /// Quit for loop
|
||||
}
|
||||
else if (candidateLen == dataToProcess.Length)
|
||||
{
|
||||
/// All bytes considered but no valid telegram found
|
||||
string s = Telegram.LogTelegram(string.Format("{0} - Invalid data received ", Name), dataToProcess);
|
||||
Debug.WriteLine(s);
|
||||
log.Debug(s);
|
||||
return;
|
||||
offset += candidateLen;
|
||||
lastValidOffset = offset;
|
||||
anyProcessed = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!anyProcessed) offset++;
|
||||
}
|
||||
}
|
||||
while (offset <= rcvdBytesCount - 4);
|
||||
|
||||
/// Remove processed data from the receive buffer
|
||||
for (int i = lastValidOffset; i < rcvdBytesCount; i++)
|
||||
{
|
||||
rcvdData[i - lastValidOffset] = rcvdData[i];
|
||||
}
|
||||
rcvdBytesCount -= lastValidOffset;
|
||||
}
|
||||
|
||||
/// <summary>Run this device</summary>
|
||||
public void RunDeviceAfter()
|
||||
|
||||
@ -24,9 +24,10 @@ namespace TBF.Rig.Modbus.Easytherm
|
||||
|
||||
public float requiredTemp { get { return easythermCfg.ProcParams.RequiredTemp; } }
|
||||
|
||||
public Easytherm()
|
||||
{
|
||||
}
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
|
||||
public Easytherm() { }
|
||||
|
||||
public Easytherm(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@ -47,6 +48,7 @@ namespace TBF.Rig.Modbus.Easytherm
|
||||
temperatureSetPointValid = false;
|
||||
temperatureSetPointRequested = false;
|
||||
actualTemperatureIsValid = false;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
}
|
||||
|
||||
/// <summary>Run this device</summary>
|
||||
@ -81,26 +83,31 @@ namespace TBF.Rig.Modbus.Easytherm
|
||||
// StateMachine.ControlBoard.UpdateUI("ReservoirTemp", easythermCfg.ReservoirNr, actualTemperature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!temperatureSetPointValid && !temperatureSetPointRequested)
|
||||
{
|
||||
RequestTemperatureSetpoint();
|
||||
temperatureSetPointRequested = true;
|
||||
}
|
||||
else if (temperatureSetPointValid && requiredTemp != temperatureSetPoint)
|
||||
{
|
||||
SetTemperatureSetpoint(requiredTemp);
|
||||
log.InfoFormat("{0} - Set new temperature setpoint = {1}", Name, requiredTemp);
|
||||
}
|
||||
else if ((StateMachine.Time % 10) == (easythermCfg.ModbusAddress % 10)) /// This is to prevent overflow of the Modbus component queue for sending data
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (easythermCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
easythermCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation)
|
||||
{
|
||||
RequestActualTemperature();
|
||||
if (!temperatureSetPointValid && !temperatureSetPointRequested)
|
||||
{
|
||||
RequestTemperatureSetpoint();
|
||||
temperatureSetPointRequested = true;
|
||||
}
|
||||
else if (temperatureSetPointValid && requiredTemp != temperatureSetPoint)
|
||||
{
|
||||
SetTemperatureSetpoint(requiredTemp);
|
||||
log.InfoFormat("{0} - Set new temperature setpoint = {1}", Name, requiredTemp);
|
||||
}
|
||||
else if (modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
RequestActualTemperature();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
@ -20,6 +20,6 @@ namespace TBF.Rig.Modbus
|
||||
|
||||
public static class Constants
|
||||
{
|
||||
public const int ModbusPollPeriod = 4;
|
||||
public const int ModbusPollPeriod = 5;
|
||||
}
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
public double MeasuredVal { get { return receivedPressure; } }
|
||||
public string AltString { get { return string.Empty; } }
|
||||
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
|
||||
public PressureMeter() { }
|
||||
|
||||
@ -42,7 +44,10 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
///
|
||||
/// IDevice interface
|
||||
///
|
||||
public void Initialize() { }
|
||||
public void Initialize()
|
||||
{
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
@ -71,8 +76,13 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
log.WarnFormat("Pressure: {0}={1}bar", Name, receivedPressure.ToString("F3"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((StateMachine.Time % Constants.ModbusPollPeriod) == (pressureMtrCfg.ModbusAddress % Constants.ModbusPollPeriod)) /// Each 'ModbusDevices' seconds
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (pressureMtrCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
pressureMtrCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
const byte Function = 4; /// Read input registers
|
||||
const ushort Address = 0; /// Pressure
|
||||
@ -80,7 +90,6 @@ namespace TBF.Rig.Modbus.PressureMeter.Meret
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
@ -42,9 +42,10 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
public double MeasuredVal { get { return ReadTemperature(); } }
|
||||
public string AltString { get { return "Invalid format"; } }
|
||||
|
||||
public TempMeter()
|
||||
{
|
||||
}
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
|
||||
public TempMeter() { }
|
||||
|
||||
public TempMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@ -89,7 +90,15 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
return calendarEvents;
|
||||
}
|
||||
|
||||
public void Initialize() { }
|
||||
public void Initialize()
|
||||
{
|
||||
/// Only TempMeter with Channel == 0 communicates via the parent Modbus component
|
||||
if (Channel == 0)
|
||||
{
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceBefore()
|
||||
{
|
||||
if (Channel != 0 ||
|
||||
@ -104,7 +113,7 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
///
|
||||
if (modbus.ReceivedTelegrams[0].Count > 0)
|
||||
{
|
||||
byte[] telegram = modbus.ReceivedTelegrams[GrochAddress].Dequeue();
|
||||
byte[] telegram = modbus.ReceivedTelegrams[0].Dequeue();
|
||||
if (telegram.Length == 28)
|
||||
{
|
||||
byte checksum = 0;
|
||||
@ -138,17 +147,12 @@ namespace TBF.Rig.Modbus.TempMeter.Groch
|
||||
}
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (Channel != 0 ||
|
||||
tempMtrCfg.DebugLevel == Config.Entities.DebugMode.Simulate ||
|
||||
tempMtrCfg.DebugLevel == Config.Entities.DebugMode.FailureDuringOperation)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
///
|
||||
/// Only TempMeter with Channel == 0 communicates via the parent Modbus component
|
||||
///
|
||||
if ((StateMachine.Time % Constants.ModbusPollPeriod) == Constants.ModbusPollPeriod) /// Each 'ModbusDevices' seconds
|
||||
|
||||
if (Channel == 0 &&
|
||||
tempMtrCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
tempMtrCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
modbus.SendMessageGroch(new byte[] { 0x20, 0x20, 0x20, 0x20, 0x10, 2, 1, 3, 6, 0x16 });
|
||||
}
|
||||
|
||||
@ -25,6 +25,8 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
public double MeasuredVal { get { return receivedTemp; } }
|
||||
public string AltString { get { return string.Empty; } }
|
||||
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
|
||||
public TempMeter() { }
|
||||
|
||||
@ -42,7 +44,10 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
///
|
||||
/// IDevice interface
|
||||
///
|
||||
public void Initialize() { }
|
||||
public void Initialize()
|
||||
{
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
}
|
||||
|
||||
/// <summary>Run this device</summary>
|
||||
public void RunDeviceBefore()
|
||||
@ -72,8 +77,13 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
log.WarnFormat("Temperature: {0}={1}°C", Name, receivedTemp.ToString("F1"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((StateMachine.Time % Constants.ModbusPollPeriod) == (tempMtrCfg.ModbusAddress % Constants.ModbusPollPeriod)) /// Each 'ModbusDevices' seconds
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (tempMtrCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
tempMtrCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
const byte Function = 4; /// Read input registers
|
||||
const ushort Address = 0; /// Temperature
|
||||
@ -81,7 +91,6 @@ namespace TBF.Rig.Modbus.TempMeter.Meret
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
@ -36,10 +36,10 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
|
||||
int msrmntTimeStamp;
|
||||
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
public LevelMeter()
|
||||
{
|
||||
}
|
||||
|
||||
public LevelMeter() { }
|
||||
|
||||
public LevelMeter(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@ -72,6 +72,7 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
}
|
||||
|
||||
msrmntState = MsrmntState.Busy;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
|
||||
log.FatalFormat("Successfully initialized device {0}", ToString());
|
||||
}
|
||||
@ -124,11 +125,13 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
Debug.WriteLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
|
||||
if ((StateMachine.Time % 3) == 0) /// Each 3 seconds
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (myCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
myCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
///
|
||||
/// Read distance, level, quantity, percentage and temperature in IEEE754 (DWORD-s)
|
||||
@ -137,17 +140,15 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
UInt16 count = 5;
|
||||
|
||||
/// Prepare data to be sent
|
||||
byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
msg[0] = myCfg.ModbusAddress;
|
||||
msg[1] = 3; /// CMD =
|
||||
msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
|
||||
msg[3] = (byte)(regAddr & 0xFF); /// Control Word Lo
|
||||
msg[4] = (byte)(count >> 8); /// Serial Com Reference Hi
|
||||
msg[5] = (byte)(count & 0xFF); /// Serial Com Reference Lo
|
||||
|
||||
modbus.SendMessage(msg);
|
||||
}
|
||||
else if ((StateMachine.Time % 3) == 1) /// Each 3 seconds
|
||||
{
|
||||
|
||||
/////
|
||||
///// Read STATUS1
|
||||
/////
|
||||
@ -155,17 +156,15 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
//UInt16 count = 1;
|
||||
|
||||
///// Prepare data to be sent
|
||||
//byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
//msg[0] = myCfg.ModbusAddress;
|
||||
//msg[1] = 3; /// CMD =
|
||||
//msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
|
||||
//msg[3] = (byte)(regAddr & 0xFF); /// Control Word Lo
|
||||
//msg[4] = (byte)(count >> 8); /// Serial Com Reference Hi
|
||||
//msg[5] = (byte)(count & 0xFF); /// Serial Com Reference Lo
|
||||
|
||||
//modbus.SendMessage(msg);
|
||||
}
|
||||
else if ((StateMachine.Time % 3) == 2) /// Each 3 seconds
|
||||
{
|
||||
|
||||
/////
|
||||
///// Read distance, level, quantity, percentage and temperature in IEEE754 (DWORD-s)
|
||||
/////
|
||||
@ -173,18 +172,17 @@ namespace TBF.Rig.Modbus.UltrasoundLevelMeter
|
||||
//UInt16 count = 10;
|
||||
|
||||
///// Prepare data to be sent
|
||||
//byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
//msg[0] = myCfg.ModbusAddress;
|
||||
//msg[1] = 3; /// CMD =
|
||||
//msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
|
||||
//msg[3] = (byte)(regAddr & 0xFF); /// Control Word Lo
|
||||
//msg[4] = (byte)(count >> 8); /// Serial Com Reference Hi
|
||||
//msg[5] = (byte)(count & 0xFF); /// Serial Com Reference Lo
|
||||
|
||||
//modbus.SendMessage(msg);
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
}
|
||||
|
||||
@ -33,10 +33,10 @@ namespace TBF.Rig.Modbus.WaterAnalyzer
|
||||
/// <summary>Measurement time stamp when MsrmntState == MsrmntState.Valid</summary>
|
||||
int msrmntTimeStamp;
|
||||
|
||||
int ticketNumber; /// 1 .. number of devices registered for regular polling
|
||||
|
||||
public Analyzer()
|
||||
{
|
||||
}
|
||||
|
||||
public Analyzer() { }
|
||||
|
||||
public Analyzer(Generic.IComponentCfg cfg, IList<Generic.IComponent> components)
|
||||
: base(cfg)
|
||||
@ -66,6 +66,7 @@ namespace TBF.Rig.Modbus.WaterAnalyzer
|
||||
}
|
||||
|
||||
msrmntState = MsrmntState.Busy;
|
||||
ticketNumber = modbus.RegisterForPolling();
|
||||
|
||||
log.FatalFormat("Successfully initialized device {0}", ToString());
|
||||
}
|
||||
@ -107,11 +108,13 @@ namespace TBF.Rig.Modbus.WaterAnalyzer
|
||||
Debug.WriteLine(line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
|
||||
if ((StateMachine.Time % 10) == 0) /// Each 10 seconds
|
||||
public void RunDeviceAfter()
|
||||
{
|
||||
if (myCfg.DebugLevel != Config.Entities.DebugMode.Simulate &&
|
||||
myCfg.DebugLevel != Config.Entities.DebugMode.FailureDuringOperation &&
|
||||
modbus.IsMyTurn(ticketNumber))
|
||||
{
|
||||
///
|
||||
/// Send command to request 1 float value in 2 registers at addresses 0x50 and 0x51 from Modbus.WaterAnalyzer
|
||||
@ -120,6 +123,7 @@ namespace TBF.Rig.Modbus.WaterAnalyzer
|
||||
UInt16 count = 2;
|
||||
|
||||
/// Prepare data to be sent
|
||||
byte[] msg = new byte[8]; /// Buffer for data to send
|
||||
msg[0] = myCfg.ModbusAddress;
|
||||
msg[1] = 3; /// CMD =
|
||||
msg[2] = (byte)(regAddr >> 8); /// Control Word Hi
|
||||
@ -131,7 +135,6 @@ namespace TBF.Rig.Modbus.WaterAnalyzer
|
||||
}
|
||||
}
|
||||
|
||||
public void RunDeviceAfter() { }
|
||||
public void StopDevice() { }
|
||||
public void StopDevice2() { }
|
||||
|
||||
|
||||
@ -812,9 +812,12 @@ namespace TBF.Rig
|
||||
{
|
||||
Thread.Sleep(100); /// Insert 1/10 sec.delay between RunOperations() and RunDeviceAfter()
|
||||
|
||||
foreach (var device in devices)
|
||||
/// Call RunDeviceAfter() functions in reversed order
|
||||
/// so that the parent compnent's RunDeviceAfter()
|
||||
/// is called after RunDeviceAfter() of it's children.
|
||||
for (int i = devices.Count - 1; i >= 0; i--)
|
||||
{
|
||||
device.RunDeviceAfter();
|
||||
devices[i].RunDeviceAfter();
|
||||
}
|
||||
|
||||
WaitNextTick();
|
||||
|
||||
Loading…
Reference in New Issue
Block a user